2016-11-22 122 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 
相关问题