有没有一种方法可以将列名指定为参数?

时间:2020-04-14 18:46:13

标签: r function arguments

举例来说,我想创建一个复制选择列的函数。

testdata <- data.frame(
  "diff1" = c(seq(1:10)),
  "diff2" = c(seq(21:30))
)

goal <- testdata %>%
  mutate(newdiff1 = diff1)

所以我创建了一个函数

funtest <- function(dat,var,newvar){
  dat %>%
    mutate(newvar = var)
}

但是

test2 <- funtest(testdata,diff1,newdiff1)

将返回错误:

 Error: object 'diff1' not found 

此格式有效

nondesiredformat <- funtest(testdata,testdata$diff1,newdiff1)

但这会导致新变量始终被称为“ newvar”,而不是我们的第三个参数。

有没有一种方法可以更改功能,以便test2中的参数可以工作?

谢谢

3 个答案:

答案 0 :(得分:1)

在函数中,我们可以使用{{}}进行求值,即!! + enquo对于传递给函数的未加引号的变量名和赋值,请使用:==

funtest <- function(dat,var,newvar){
   dat %>%
     mutate({{newvar}} := {{var}})
        }
funtest(testdata, diff1, newdiff1)
#    diff1 diff2 newdiff1
#1      1     1        1
#2      2     2        2
#3      3     3        3
#4      4     4        4
#5      5     5        5
#6      6     6        6
#7      7     7        7
#8      8     8        8
#9      9     9        9
#10    10    10       10

答案 1 :(得分:1)

您可以为此使用bquote:

eval(bquote(
  dat %>% 
    mutate(.(newvar) := .(var))
))

您还可以根据自己的情况更新旧学校

dat[[newvar]] = dat[[var]]

答案 2 :(得分:0)

如果您开始使用带有参数的变量名编写函数,则可能会发现data.tabledplyr更方便。我最近写了post on the subject。我认为,data.tabledplyr更容易处理标准评估。

使用data.table,您可以通过多种方式将列名用作参数

使用get

您可以使用get来将名称与某个范围内的值映射。这是您的data.table的范围:

library(data.table)
funtest <- function(dat,var,newvar){
  dat[, (newvar) := get(var)]
}

:=是一个按引用更新的运算符。如果您想了解更多信息,data.table插图是一个很好的起点。调用函数:

dt = data.table(iris)

funtest(dt, "Species","x")[]
     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species         x
  1:          5.1         3.5          1.4         0.2    setosa    setosa
  2:          4.9         3.0          1.4         0.2    setosa    setosa
  3:          4.7         3.2          1.3         0.2    setosa    setosa
  4:          4.6         3.1          1.5         0.2    setosa    setosa
  5:          5.0         3.6          1.4         0.2    setosa    setosa
 ---                                                                      
146:          6.7         3.0          5.2         2.3 virginica virginica
147:          6.3         2.5          5.0         1.9 virginica virginica
148:          6.5         3.0          5.2         2.0 virginica virginica
149:          6.2         3.4          5.4         2.3 virginica virginica
150:          5.9         3.0          5.1         1.8 virginica virginica

使用.SD

您还可以使用.SD表示数据子集。当您引用了多个变量时,这更方便。它避免了!!!rlang::sym所必需的dplyr

您会发现自己使用非常简洁的语法进行复杂的计算:

df[, newcolnames := lapply(.SD, mean), by = grouping_var, .SDcols = xvars]