【问题标题】:R, pass column name as argument to function using dplyr::filter() and %in%R,使用 dplyr::filter() 和 %in% 将列名作为参数传递给函数
【发布时间】:2015-04-04 03:24:49
【问题描述】:

如何在类似于问题here 但使用dplyr 链接和filter() 以及%in% 的函数中传递列名。

require(dplyr)
set.seed(8)
df <- data.frame(
  A=sample(c(1:3), 10, replace=T), 
  B=sample(c(1:3), 10, replace=T))

如果想获取 A 列为 1 或 2 的行,我可以这样做:

df %>% filter(A %in% c(1,2))

我明白了:

  A B
1 2 3
2 1 2
3 1 3
4 2 1
5 1 1
6 1 3

现在,我怎样才能把它放在一个可以指定列的函数中,这不起作用:

fun1 <- function(x, column, n){
  res <- 
    x %>% filter(column %in% n)
  return(res)
}
fun1(df, A, c(1,2))

【问题讨论】:

    标签: r filter dplyr


    【解决方案1】:

    你可以试试

    fun1 <- function(x, column, n){
     x %>% 
      filter_(lazyeval::interp(quote(x %in% y), x=as.name(column), y=n))
     }
    fun1(df, 'A', 1:2)
    

    或者

    fun2 <- function(x, column, n){
       args <- as.list(match.call())
       x %>%
         filter(eval(args$column, x) %in% n)
     }
    
     fun2(df, A, 1:2)
    

    【讨论】:

    • 这是现在看到的好东西。不久前我问了一个类似的问题时,@aosmith 提供了一个很好的答案。在这里,我看到了一个更新的版本。今天我在做笔记。 :) +1
    • @akrun 您能否解释一下您的选项 2 - match.call() 是否包含放入函数中的所有参数? filter() in eval() 是如何解释的?
    • @user3375672 是的,match.call() 包含所有参数。在这里,数据集是列的envir(即x)。请查看?eval
    【解决方案2】:

    如果您想保留自己的功能,请尝试:

    fun1 <- function(x, column, n){
      res <- x %>% filter_(paste(column,"%in%",n))
      return(res)
    }
    
    fun1(df, "A", "c(1,2)")
    

    【讨论】:

      【解决方案3】:

      尝试将您的功能更改为

      fun1 <- function(x, column, n){
          require(lazyeval)
          filter_(x,
              interp(quote(col %in% n),
                  col = lazy(column), n = n))
      }
      
      all(fun1(df, A, c(1, 2)) == filter(df, A %in% c(1,2)))
      # TRUE
      

      【讨论】:

        猜你喜欢
        • 2018-05-09
        • 1970-01-01
        • 2017-10-16
        • 1970-01-01
        • 1970-01-01
        • 2021-01-19
        • 2015-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多