Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何在列上使用tidyeval进行变异?_R_Dplyr_Tidyeval - Fatal编程技术网

R 如何在列上使用tidyeval进行变异?

R 如何在列上使用tidyeval进行变异?,r,dplyr,tidyeval,R,Dplyr,Tidyeval,很抱歉造成混淆,但最终,我发布的第一个示例(在页面底部)没有帮助我了解tidyeval如何与mutate一起工作,因此我添加了一个新示例 我想创建一个包含三个参数的函数: 数据帧 要变异的列 一个变量(来自数据帧),用于替换正在变异的值 例如,要将mpg中的值替换为carb中的值,我尝试了以下方法: I tried this colToX <- function(dt, ..., repl) { cols <- quos(...) repl <- quo(repl)

很抱歉造成混淆,但最终,我发布的第一个示例(在页面底部)没有帮助我了解tidyeval如何与mutate一起工作,因此我添加了一个新示例

我想创建一个包含三个参数的函数:

  • 数据帧
  • 要变异的列
  • 一个变量(来自数据帧),用于替换正在变异的值
例如,要将
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)
错误:LHS必须是名称或字符串

最终,输出应该与mutate(mtcars,mpg=1)相同。

因为错误是“error:LHS必须是一个名称或字符串”,其中LHS表示左手边,它具体指的是
!!列:=1
部分。你需要将你制作的quosure转换成字符串或符号。使用
quo\u name

colTo1 <- function(dt, ...) {
    col <- quo_name(quo(...))
    mutate(mtcars, !!col := 1)
}

colTo1@MrFlick的解决方案适用于单列情况,但由于OP使用了
..
作为参数,我假设OP也希望函数能够容纳多个列。例如,以下操作不起作用:

colTo1 <- function(dt, ...) {
  col <- quo_name(quo(...))
  mutate(dt, !!col := 1)
}

colTo1(mtcars, mpg, cyl)
quos
..
中的每个参数转换为quosure的向量。使用
mutate_at
vars
语法和显式拼接
rlang
,我们可以在
cols
中取消引用每个quosure,并在指定的列上进行变异

现在,它可以按预期工作:

colTo1(mtcars, mpg, cyl)
结果:

   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
...
   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  110 110 160.0 110 3.90 2.620 16.46  0  1    4    4
2  110 110 160.0 110 3.90 2.875 17.02  0  1    4    4
3   93  93 108.0  93 3.85 2.320 18.61  1  1    4    1
4  110 110 258.0 110 3.08 3.215 19.44  1  0    3    1
5  175 175 360.0 175 3.15 3.440 17.02  0  0    3    2
6  105 105 225.0 105 2.76 3.460 20.22  1  0    3    1
7  245 245 360.0 245 3.21 3.570 15.84  0  0    3    4
8   62  62 146.7  62 3.69 3.190 20.00  1  0    4    2
9   95  95 140.8  95 3.92 3.150 22.90  1  0    4    2
10 123 123 167.6 123 3.92 3.440 18.30  1  0    4    4
...
将“
1
”作为另一个参数传递到函数中也很容易:

colToX <- function(dt, ..., X) {
  cols <- quos(...)
  mutate_at(dt, vars(!!!cols), function(x) x=X)
}

colToX(mtcars, mpg, cyl, X = 2)
在这里,我使用
funs
函数创建一个函数调用列表,这些函数调用从
vars
引用的每个列
.data
是指在
处将数据帧输入到
mutate_中(在本例中为
dt
)。我使用
enquo
将调用的内容从
X
转换为quosure,并使用
将其解压缩

结果:

   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
...
   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  110 110 160.0 110 3.90 2.620 16.46  0  1    4    4
2  110 110 160.0 110 3.90 2.875 17.02  0  1    4    4
3   93  93 108.0  93 3.85 2.320 18.61  1  1    4    1
4  110 110 258.0 110 3.08 3.215 19.44  1  0    3    1
5  175 175 360.0 175 3.15 3.440 17.02  0  0    3    2
6  105 105 225.0 105 2.76 3.460 20.22  1  0    3    1
7  245 245 360.0 245 3.21 3.570 15.84  0  0    3    4
8   62  62 146.7  62 3.69 3.190 20.00  1  0    4    2
9   95  95 140.8  95 3.92 3.150 22.90  1  0    4    2
10 123 123 167.6 123 3.92 3.440 18.30  1  0    4    4
...

OP可能还想更改
mutate
调用中的硬编码
mtcars
。@JakeKaupp是的,很抱歉这是一个打字错误,我应该用
dt
替换它。我意识到我的示例对于我最初的问题有点有限,我需要在
之后传递一个变量,而不是1:=
。你能概括一下那个案子吗?或者我应该发布一个新的问题…@Dambo更新了我的答案。看看这是否是你想要的。我的意思是能够通过类似于
colToX(mtcars,mpg,cyl,X=mpg)
,其中
mpg
是来自
mtcars
@Dambo的变量。我编辑了我的答案,以解决你的“新”需求。一般来说,SO社区不赞成有一个初始问题,接受一个答案,改变原来的问题,然后拒绝接受接受的答案。因此,我建议下次提问时,提供回答者解决你“真实”问题所需的所有必要细节,尽量不要戏剧性地改变你的问题。我接受了asnwer,因为我最初是这么做的,但当我在mutate_impl(.data,dots)中运行你的新代码
error时,我遇到了一个错误:计算错误:无效的下标类型“语言”
   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  110 110 160.0 110 3.90 2.620 16.46  0  1    4    4
2  110 110 160.0 110 3.90 2.875 17.02  0  1    4    4
3   93  93 108.0  93 3.85 2.320 18.61  1  1    4    1
4  110 110 258.0 110 3.08 3.215 19.44  1  0    3    1
5  175 175 360.0 175 3.15 3.440 17.02  0  0    3    2
6  105 105 225.0 105 2.76 3.460 20.22  1  0    3    1
7  245 245 360.0 245 3.21 3.570 15.84  0  0    3    4
8   62  62 146.7  62 3.69 3.190 20.00  1  0    4    2
9   95  95 140.8  95 3.92 3.150 22.90  1  0    4    2
10 123 123 167.6 123 3.92 3.440 18.30  1  0    4    4
...