【问题标题】:Using if_else or case_when to conditionally filter a dataframe in two different ways使用 if_else 或 case_when 以两种不同的方式有条件地过滤数据帧
【发布时间】:2021-07-01 20:37:58
【问题描述】:

最小的例子 - 我有 9 个来自 3 个受试者的问卷回答,其中包含两个问题:

set.seed(1)
df <- data.frame(ID = c(rep("A", 2), rep("B", 3), rep("C", 4)),
                 Q1 = sample(0:5, 9, replace=T),
                 Q2 = sample(1:7, 9, replace=T),
                 Days_Used = c(rep(10, 2), rep(5, 3), rep(4, 4))
)

将 Days_Used 视为 End_Date - Start_Date。我想以两种方式之一过滤数据框 - 按 Days_Used 或填写问卷的次数(即按与主题关联的行数),具体取决于变量 FILTER_BY_DAYS_USED 是否为 TRUEFALSE。我尝试了以下方法:

FILTER_BY_DAYS_USED <- TRUE
df %>% 
  group_by(ID) %>%
  if_else(FILTER_BY_DAYS_USED,
          filter(Days_Used >= 5),
          filter(n() >= 3))

但是当我执行它时得到一个错误消息

Error: `condition` must be a logical vector, not a grouped_df/tbl_df/tbl/data.frame` object.

我想获得以下输出:

  1. FILTER_BY_DAYS_USEDTRUE时:前5行对应科目A和B

  2. FILTER_BY_DAYS_USEDFALSE时:最后7行对应主题B和C

我的条件过滤器的正确语法是什么?

在此先感谢

托马斯·飞利浦

【问题讨论】:

    标签: r filter dplyr case


    【解决方案1】:

    你的方向是对的。尝试使用if/else,因为这是一个标量比较。

    library(dplyr)
    
    FILTER_BY_DAYS_USED <- TRUE
    
    df %>% 
      group_by(ID) %>%
      filter(if(FILTER_BY_DAYS_USED) Days_Used >= 5 else n() >= 3) %>%
      ungroup
    
    #   ID       Q1    Q2 Days_Used
    #  <chr> <int> <int>     <dbl>
    #1 A         0     3        10
    #2 A         3     1        10
    #3 B         0     5         5
    #4 B         1     5         5
    #5 B         4     2         5
    

    【讨论】:

    • 语法中没有逗号是惊人的。 - 只有else 的存在充当分隔符。另外,虽然我现在不需要它,但我很好奇:在进行向量比较时,语法会如何改变?
    • 对于一般的矢量比较,您可以使用ifelse/if_else 等。不过,矢量比较的示例是什么?
    • 向量比较的一个例子是在过滤器中使用多重比较,尽管我认为可以使用 |和 &。一个更困难的例子是基于同一列中早期值的函数进行过滤(根据 FILTER_BY_DAYS_USED 的值选择不同的列。在我看来,这需要一个循环。
    • 是的,这实际上取决于您的实际用例。如果你有另一个像 FILTER_BY_DAYS_USED 这样的标志,是的,它可以用 &amp;| 完成。
    猜你喜欢
    • 2021-06-02
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2016-09-23
    相关资源
    最近更新 更多