【问题标题】:R data frame subsetting based on a column value frequency threshold [duplicate]基于列值频率阈值的R数据框子集[重复]
【发布时间】:2017-04-06 07:33:40
【问题描述】:

我是新的 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 行将被删除,因为它是“B”的第 4 次出现,但“B”的前 3 行已被保留。

我已经阅读了多篇文章,这些文章演示了如何删除行总数小于/大于累积频率值(例如 4)的变量的所有行。例如,我尝试过:

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

这种方法只保留所有唯一出现的 V1

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 新手,所以我可能忽略了一个非常简单的解决方案。任何建议将不胜感激。

谢谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以使用data.table

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

    【讨论】:

      【解决方案2】:

      使用 dplyr 的top_n:

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

      【讨论】:

      • 嗯...这比我的解决方案简单得多。
      • Jacob - 感谢您的解决方案。效果很好。
      【解决方案3】:

      这似乎可以做到:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-27
        • 1970-01-01
        • 2014-09-10
        • 2017-02-14
        相关资源
        最近更新 更多