我很抱歉这个混乱,但最终,我发布的第一个例子(在页面底部),并没有帮助我弄清楚tidyeval如何与mutate一起工作,所以我添加了一个新的例子。
我想创建一个带三个args的函数:
例如,要使用mpg
中的值替换carb
中的值,我试过这个:
I tried this
colToX <- function(dt, ..., repl) {
cols <- quos(...)
repl <- quo(repl)
mutate_at(dt, vars(!!!cols), funs(function(x) !!repl))
}
colToX(mtcars, mpg, repl = carb)
自那以后不起作用:
mutate_impl(.data,dots)中的错误:列
mpg
不受支持 类型函数
我的第一个例子(@ MrFlick&#39; s和@ UseR&#39; s都可以正常工作):
例如,下面的那个应该mutate()
将所有1分配给...
中传递的变量
colTo1 <- function(dt, ...) {
col <- quo(...)
mutate(mtcars, !!col := 1)
}
colTo1(mtcars, mpg)
错误:LHS必须是名称或字符串
最终,输出应与mutate(mtcars, mpg = 1)
答案 0 :(得分:4)
@ MrFlick的解决方案适用于一列情况,但由于OP使用...
作为参数,我假设OP还希望该函数能够接收多列。例如,以下内容不起作用:
colTo1 <- function(dt, ...) {
col <- quo_name(quo(...))
mutate(dt, !!col := 1)
}
colTo1(mtcars, mpg, cyl)
继承错误(x,&#34; quosure&#34;):object&#39; cyl&#39;找不到
我们可以做的是使用quos
代替quo
和mutate_at
代替mutate
:
colTo1 <- function(dt, ...) {
cols <- quos(...)
mutate_at(dt, vars(!!!cols), function(x) x=1)
}
quos
将每个参数从...
转换为quosures向量。使用mutate_at
的{{1}}语法和vars
中!!!
的显式拼接,我们可以在rlang
中取消引用每个quosure,并在指定的那些上进行变异列。
现在这可以按预期工作:
cols
<强>结果:强>
colTo1(mtcars, mpg, cyl)
它也很容易让#34; mpg cyl disp hp drat wt qsec vs am gear carb
1 1 1 160.0 110 3.90 2.620 16.46 0 1 4 4
2 1 1 160.0 110 3.90 2.875 17.02 0 1 4 4
3 1 1 108.0 93 3.85 2.320 18.61 1 1 4 1
4 1 1 258.0 110 3.08 3.215 19.44 1 0 3 1
5 1 1 360.0 175 3.15 3.440 17.02 0 0 3 2
6 1 1 225.0 105 2.76 3.460 20.22 1 0 3 1
7 1 1 360.0 245 3.21 3.570 15.84 0 0 3 4
8 1 1 146.7 62 3.69 3.190 20.00 1 0 4 2
9 1 1 140.8 95 3.92 3.150 22.90 1 0 4 2
10 1 1 167.6 123 3.92 3.440 18.30 1 0 4 4
...
&#34;是另一个传递给函数的参数:
1
修改:OP将问题更改为要求colToX <- function(dt, ..., X) {
cols <- quos(...)
mutate_at(dt, vars(!!!cols), function(x) x=X)
}
colToX(mtcars, mpg, cyl, X = 2)
应该是同一数据框中的另一列。以下是我的新解决方案:
X
在这里,我使用colToX <- function(dt, ..., X) {
cols <- quos(...)
X_quo <- enquo(X)
mutate_at(dt, vars(!!!cols), funs(.data$`!!`(X_quo)))
}
colToX(mtcars, mpg, cyl, X = hp)
函数创建一个对funs
引用的每列的函数调用列表。 vars
将输入数据框称为.data
(在本例中为mutate_at
)。我使用dt
将从enquo
调用的内容转换为quosure,并使用X
取消引用它。
<强>结果:强>
!!
答案 1 :(得分:2)
由于错误显示“错误:LHS必须是名称或字符串”,其中LHS表示左侧,它特别指的是!!col := 1
部分。您需要将您制作的quosure转换为字符串或符号。使用quo_name
colTo1 <- function(dt, ...) {
col <- quo_name(quo(...))
mutate(mtcars, !!col := 1)
}