2016-11-22 105 views
1

我是一個新的R用戶,這是我第一次提交的問題(希望符合協議)。基於列值頻率閾值的R數據幀子集化

我有一個數據框有兩列。

df <- data.frame(v1 = c("A", "A", "B", "B", "B", "B", "C", "D", "D", "E")) 
dfc <- df %>% count(v1) 
df$n <- with(dfc, n[match(df$v1,v1)]) 

    v1 n 
1 A 2 
2 A 2 
3 B 4 
4 B 4 
5 B 4 
6 B 4 
7 C 1 
8 D 2 
9 D 2 
10 E 1 

我想要刪除超過v1出現值3次出現閾值的行。該值小於閾值的所有行均被保留。在這個例子中,我想刪除第6行並保留子集數據框中的所有剩餘行。

其結果將包括用於V1以下值:爲「B」

v1 
1 A 
2 A 
3 B 
4 B 
5 B 
6 C 
7 D 
8 D 
9 E 

第6行會被刪除,因爲它是的「B」的第四發生,但3個前面的行已被保留。

我已閱讀多個帖子,演示如何與行總計比的累積頻率值小於/大於刪除一個變量的所有行,例如4。例如,我曾嘗試:

df1 <- df %>% 
    group_by(v1) %>% 
    filter(n() < 4) 

這方法只保留所有唯一出現的V1爲<的行。6行是子集。

df2 <- df %>% 
    group_by(v1) %>% 
    filter(n() > 3) 

該方法僅保留所有唯一出現的v1大於3的行。4行是子集。

df4 <- subset(df, v1 %in% names(table(df$v1))[table(df$v1) <4]) 

該方法與第一種方法具有相同的結果。

這些方法都不會產生我需要的結果。

如前所述,我需要保留v1 =「B」的前三行,並且只有當該值出現3次時才刪除行。

因爲我是R新手,可能我忽略了一個非常簡單的解決方案。任何建議將不勝感激。

謝謝。

回答

1

使用dplyr的top_n

df %>% group_by(v1) %>% top_n(3) 
+0

嗯...這是不是我的解決方案簡單得多。 – William

+0

Jacob - 感謝您的解答。它效果很好。 – danbret

0

我們可以使用data.table

library(data.table) 
setDT(df)[, if(.N >3) head(.SD, 3) else .SD , v1] 
0

這似乎做到這一點:

index <- vector("numeric", nrow(df)) 

for (i in 1:nrow(df)) { 
    if (sum(df[1:i, ] == as.character(df[i, 1])) <= 3) { 

    index[i] <- i 

    } else { 

    cat(i) 
    } 

} 


df[index, ] 
    v1 n 
1 A 2 
2 A 2 
3 B 4 
4 B 4 
5 B 4 
7 C 1 
8 D 2 
9 D 2 
10 E 1