为什么dplyr filter()不能在函数内工作(即使用变量作为列名)?

时间:2017-07-23 03:57:23

标签: r filter dplyr

使用dplyr函数过滤,分组和变异数据的函数。基本管道序列在函数外部工作很好,这是我使用真正的列名称的地方。把它放在一个函数中,其中列名是一个变量,一些函数可以工作但有些并不是最显着的dplyr :: filter()。例如:

var1 <- c('yes', NA, NA, 'yes', 'yes', NA, NA, NA, 'yes', NA, 'no', 'no', 'no', 'maybe', NA, 'maybe', 'maybe', 'maybe')

var2 <- c(1:18)

df <- data.frame(var1, var2)

这样可以正常工作(即过滤NA):

df%>%filter(!is.na(var1))

......但这不是:

x <- "var1"

df%>%filter(!is.na(x))

......但这样做:

df%>%select(x)

这是NA需要专门过滤掉的。

尝试得到(“x”),没有好处,切片:

df[!is.na(x),]

......也没有好处。

有关如何传递变量以过滤函数内部(或外部)以及变量为何与其他dplyr函数一起使用的任何想法?

4 个答案:

答案 0 :(得分:2)

我们可以使用sym转换为符号,然后使用UQ对其进行评估

library(rlang)
library(dplyr)
df %>%
   filter(!is.na(UQ(sym(x))))
#     var1 var2
#1    yes    1
#2    yes    4
#3    yes    5
#4    yes    9
#5     no   11
#6     no   12
#7     no   13
#8  maybe   14
#9  maybe   16
#10 maybe   17
#11 maybe   18

答案 1 :(得分:1)

由于我的声誉不足以在上面评论......我建议在这里查看我的答案:https://stackoverflow.com/a/45265617/6238025

  

如果您想使用dplyr创建功能,则需要按照此网页上的说明进行操作:https://rpubs.com/hadley/dplyr-programming

library(tidyverse)
var1 <- c('yes', NA, NA, 'yes', 
          'yes', NA, NA, NA, 'yes', NA, 'no', 
          'no', 'no', 'maybe', NA, 'maybe', 
          'maybe', 'maybe')
var2 <- c(1:18)

df <- data_frame(var1, var2)

your_function <- function(df, filter) {
      # Make filter a quosure
      filter = enquo(filter)

      df %>% 
        filter(!is.na(!!filter)) -> new_df

      return(new_df)
}
new_df <- your_function(df = df, filter = var1)

你也可以跳过函数内的filter = enquo(filter),然后你的电话会是:

your_function(df=df, filter=quo(var1))

然而,第一种方式更适合进行函数调用。您不需要记住quo()

这应该有用!

答案 2 :(得分:1)

有一个新的软件包 seplyr ,它将标准评估标准传递给dplyr。试试看。您可以将正常的引用代码通过它传递给dplyr。它使得在dplyr中传递参数和编写函数变得更容易。

&#xA;&#xA;

对于你的情况:

&#xA;&#xA;
  install。包(“seplyr”)&#xA;库(seplyr)&#xA; x&lt;  - “var1”&#xA; df%&gt;%filter_se(paste0(“!is.na(”,x,“)” ))&#XA;  
&#XA;

答案 3 :(得分:0)

这也可以,并且它更简单 - 只需引用包含方括号之间的列名的变量,并使用(。)来引用输入df:

cout<< it->second<<endl;

请注意,这也适用于函数:

> df %>% filter(!is.na((.)[x]))
    var1 var2
1    yes    1
2    yes    4
3    yes    5
4    yes    9
5     no   11
6     no   12
7     no   13
8  maybe   14
9  maybe   16
10 maybe   17
11 maybe   18