1

我想使用mutate()多个变量across()

  1. 使用预先定义的函数
  2. 引用数据框中的其他变量,但
  3. 只需要一个参数(要变异的变量)和
  4. 不会对函数内部的这些变量的环境进行硬编码。

例如,此代码将变量添加x到每个yz

library(dplyr)

# Data to modify
dtmp = tibble(x = 1:4, y = 10, z = 20)

# Function to pass to mutate(across())
addx = function(col, added){col + added}

# Any of these works
dtmp %>% mutate(across(c(y,z), addx, added=x))
dtmp %>% mutate(across(c(y,z), ~addx(.x, x)))
dtmp %>% mutate(across(c(y,z), function(var){addx(var, x)}))

可以通过在全局环境中硬编码引用来避免将第二个参数传递给addxinside :mutate(across())dtmp$x

addx = function(col){col + dtmp$x}
dtmp %>% mutate(across(c(y,z), addx))

但是,这种解决方案是有风险的。例如,如果数据帧在mutate调用之前被分组(按第四个变量),它将无法按预期运行,因为dtmp$x它的长度与组的子集yz组内的长度不同。

似乎应该可以这样编写addx,这样我们就不必在内部传递第二个参数,也mutate(across())不必dtmp$x在函数定义中进行硬编码。这可能吗?换句话说,是否有一个something(x)可以使定义中的x表达式在addx()当前数据框的环境(如内部定义mutate(across(data,...)))中被评估?

解决方案的结构看起来像

addx = function(col){col + Something(x)}
dtmp %>% mutate(across(c(y,z), addx))

示例用例:我们可能用来修改变量的一些函数可能会引用数据框中的许多其他变量,并且这些函数可能会在代码中多次使用。写出来arg1=var1, arg2=var2, arg3=var3,...是一团糟。

4

1 回答 1

3

您可以从中提取x值,cur_data()当您对数据进行分组时也可以使用该值。

library(dplyr)

dtmp = tibble(x = 1:4, y = 10, z = 20)

# Function to pass to mutate(across())
addx = function(col) {col + cur_data()$x}

dtmp %>% mutate(across(c(y,z), addx))

#      x     y     z
#  <int> <dbl> <dbl>
#1     1    11    21
#2     2    12    22
#3     3    13    23
#4     4    14    24

如果您需要该函数来引用分组变量,请改用cur_data_all(), 。

于 2021-07-03T02:08:05.563 回答