R数据帧子集基于列值频率阈值

时间:2016-11-22 14:54:12

标签: 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的以下值:

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

第6行已被删除,因为它是第4次出现“B”,但“B”的前3行已被保留。

我已阅读多篇帖子,演示如何删除行总数小于/大于累计频率值的变量的所有行,例如4.例如,我尝试过:

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

该方法仅保留V1的所有唯一出现的行<&lt; 4. 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”的前三行,如果有&gt;则只删除行。该值的3次出现。

因为我是R的新手,所以我可能会忽略一个非常简单的解决方案。任何建议将不胜感激。

感谢。

3 个答案:

答案 0 :(得分:1)

使用dplyr的top_n

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

答案 1 :(得分:0)

我们可以使用data.table

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

答案 2 :(得分: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