【问题标题】:Filter rows based on vector index instead of column name or index根据向量索引而不是列名或索引过滤行
【发布时间】:2020-09-09 20:48:43
【问题描述】:

我有一个非常简单的示例数据框 df_test 作为:

df_test <- data.frame("A" = 1:5)    

我想选择包含5的行。我知道我可以通过使用filter()命令来实现它:

df_analysis <- df_test %>% 
  filter(A == 5)    

但是,我想运行一个 for 循环(因为实际的数据集有很多变量并且很复杂),因此我不想手动逐个过滤列,而是运行一个可以选择一个列的 for 循环一次变量并相应地过滤行。对于这个例子,我创建了一个字符向量vv = c("A")

现在过滤,而不是使用列名,当我尝试将此向量索引用作:

df_analysis <- df_test %>% 
  filter(v[1] == 5)    

它产生 0 行而不是 1 行。

如何使用向量索引而不是列索引或名称来过滤行?

谢谢!

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    加上purrr,你可以这样做:

    map(.x = v,
        ~ df_test %>%
         filter(across(all_of(.x)) == 5))
    
    [[1]]
      A
    1 5
    

    【讨论】:

      【解决方案2】:

      我们可以使用base R

      df_test[df_test[[v]] == 5, , drop = FALSE]
      

      或者使用dplyr,通过转换为symbol 并评估 (!!)

      library(dplyr)
      df_test %>%
           filter(!! rlang::sym(v) == 5)
      #  A
      #1 5
      

      或者.data

      df_test %>%
            filter(.data[[v]] == 5)
      

      【讨论】:

        【解决方案3】:

        在其当前形式中,您的过滤器操作将文字字符串“A”(即v[1] 的内容)与数字 5 进行比较,这当然总是错误的,因此无法返回任何有效行。相反,您需要将变量 A(包含在 df_test 中)作为第一个参数传递给 filter()。您可以像这样使用get() 来做到这一点:

        df_analysis <- df_test %>% 
          filter(get(v[1]) == 5)
        

        这里使用purrr 的另一个解决方案确实要好得多,但我想指出为什么您的代码没有按预期工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-06-11
          • 1970-01-01
          • 2023-01-20
          • 2018-12-06
          • 2016-08-10
          • 2014-03-04
          • 1970-01-01
          相关资源
          最近更新 更多