如何将变量列表传递给函数,但又要考虑定量和引用

时间:2019-01-09 17:53:07

标签: r dplyr tidyeval

我想将变量列表传递给一个函数,但是我对引号和括弧感到困惑。

通常,我想在完成某种数据管理后(将函数应用于多个变量之后)返回df。

该函数正常工作(从用户堆栈交换answer到另一个问题稍作修改),但是在此示例中,调用是重复的。任何建议,指向阅读材料等,我将不胜感激。

library(tidyverse)
library(rlang)
library(tidyselect)

data <- data.frame(ageeeeoo = c(1,NA,3,NA,5), 
                   ageeeaah = c(NA,2,NA,4,NA),
                   numnumd  = c(1,NA,3,NA,5),
                   numfoofe = c(NA,2,NA,4,NA))



newfun <- function (var1) {

var1<-enquo(var1)
data<<-mutate(data,(!!as_name(var1)) := coalesce(!!! syms(vars_select(names(data), 
                                       starts_with(as_name(var1))))))
}


newfun(age)
newfun(num)



  ageeeeoo ageeeaah numnumd numfoofe age num
        1       NA       1       NA   1   1
       NA        2      NA        2   2   2
        3       NA       3       NA   3   3
       NA        4      NA        4   4   4
        5       NA       5       NA   5   5

我尝试查看dplyr编程文档和其他一些堆栈交换QA,但引用使我失望。我试过使用列表和列表,但会出错。

listofvars<-c("age","num")

newfun <- function (...) {

data<<-mutate(data,(!!!rlang::syms(...)) := coalesce(!!! syms(vars_select(names(data),
                                            starts_with(!!!quos(...))))))
}


  newfun(listofvars)

1 个答案:

答案 0 :(得分:1)

library(tidyverse)
library(rlang)
library(tidyselect)

data <- data.frame(ageeeeoo = c(1,NA,3,NA,5), 
                   ageeeaah = c(NA,2,NA,4,NA),
                   numnumd  = c(1,NA,3,NA,5),
                   numfoofe = c(NA,2,NA,4,NA))



newfun2 <- function (data, ...) {

  vars <- ensyms(..., .named = TRUE)
  needed <- map(
    vars,
    ~vars_select(names(data), starts_with(as_name(.x))) %>% 
    {quo(coalesce(!!!syms(.)))}
  )
  mutate(data, !!!needed)
}

data <- newfun2(data, age, num)

list_of_vars <- exprs(age, num)
data <- newfun2(data, !!!list_of_vars)
data

这首先将...的输入捕获为符号。它可以使用purrr::map来生成coalesce操作的列表。然后将它们提供给mutate。我重写了代码,以免在函数中修改全局环境;大多数R代码的工作方式都是这样,因此一般而言,除非明确指定,否则变量不会被更改。

rlang帮助和Hadley Wickham’s advanced R是很好的资源。