【问题标题】:Remove rows with zero values on a column when zero appears on all levels of a factor当因子的所有级别上都出现零时,删除列上具有零值的行
【发布时间】:2018-12-19 20:10:31
【问题描述】:

当它们出现在同一团队的所有方法中时,我想过滤掉零值行。

例如在下面的例子中team One 的错误为零,因此需要删除第 1、4 和 7 行。 因此,如果 alpha=beta=gamma=0 在特定的 team 中,则应删除那些为零的行。

+----+-------+-------+--------+
| id | team  | error | method |
+----+-------+-------+--------+
|  1 | One   |     0 | alpha  |
|  2 | Two   |   5.7 | alpha  |
|  3 | Three |     0 | alpha  |
|  4 | One   |     0 | beta   |
|  5 | Two   |     0 | beta   |
|  6 | Three |     0 | beta   |
|  7 | One   |     0 | gamma  |
|  8 | Two   |     0 | gamma  |
|  9 | Three |   6.7 | gamma  |
+----+-------+-------+--------+

结果表应该是:

+----+-------+-------+--------+
| id | team  | error | method |
+----+-------+-------+--------+
|  2 | Two   |   5.7 | alpha  |
|  3 | Three |     0 | alpha  |
|  5 | Two   |     0 | beta   |
|  6 | Three |     0 | beta   |
|  8 | Two   |     0 | gamma  |
|  9 | Three |   6.7 | gamma  |
+----+-------+-------+--------+

【问题讨论】:

    标签: r dataframe filter


    【解决方案1】:

    假设初始数据帧为df,如果team 组中的任何error 不为零,则过滤:

    library(dplyr)
    df %>% group_by(team) %>% 
           filter(any(error!=0))
    

    【讨论】:

      【解决方案2】:

      按'team'分组后,我们可以检查逻辑向量(error != 0)的sum是否大于0,即至少有一个非零元素

      library(dplyr)
      df %>% 
         group_by(team) %>% 
         filter(sum(error !=0 ) > 0)
      

      或者使用==的逻辑

      df %>%
         group_by(team) %>%
         filter(sum(error == 0) < n())
      

      数据

      df <- structure(list(id = 1:9, team = c("One", "Two", "Three", "One", 
       "Two", "Three", "One", "Two", "Three"), error = c(0, 5.7, 0, 
       0, 0, 0, 0, 0, 6.7), method = c("alpha", "alpha", "alpha", "beta", 
       "beta", "beta", "gamma", "gamma", "gamma")), class = "data.frame", 
       row.names = c(NA, -9L))
      

      【讨论】:

      • 我收到一个错误:评估错误:hash() 至少需要一列。我这样做: set_a %>% group_by(team) %>% filter(!n_distinct(set_a[error == 0]) > 1)
      【解决方案3】:

      使用 base r 的简单方法:

      subset(df, ave(error, team)!=0)
      

      这会过滤掉所有平均误差为零的teams...如果error 可能有负值(例如c(-1, -2, 3)),则可能会出现问题。

      所以更一般的情况是

      subset(df, !ave(error, team, FUN=function(x) all(x==0)))
      

      .. 或使用 akrun 回答中的一个想法:

      subset(df, ave(error %in% 0, team) < 1)
      

      【讨论】:

        猜你喜欢
        • 2019-08-02
        • 2015-07-24
        • 1970-01-01
        • 1970-01-01
        • 2023-03-17
        • 1970-01-01
        • 2015-02-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多