举例来说,我想创建一个复制选择列的函数。
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中的参数可以工作?
谢谢
答案 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.table
比dplyr
更方便。我最近写了post on the subject。我认为,data.table
比dplyr
更容易处理标准评估。
使用data.table
,您可以通过多种方式将列名用作参数
您可以使用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
表示数据子集。当您引用了多个变量时,这更方便。它避免了!!!rlang::sym
所必需的dplyr
。
您会发现自己使用非常简洁的语法进行复杂的计算:
df[, newcolnames := lapply(.SD, mean), by = grouping_var, .SDcols = xvars]