r - mutate(across()) 使用外部函数引用当前数据帧中的其他变量而不传递第二个参数

标签 r function dplyr across

我想要mutate() across() 的多个变量

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

例如,此代码将添加变量 xy 中的每一个和z :

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)}))

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

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

但是,这个解决方案是有风险的。例如,如果数据帧在 mutate 之前分组(通过某些第四个变量),它将无法按预期运行。打电话是因为dtmp$xy 的子集的长度不同或z组内。

看起来应该可以写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,...一团糟。

最佳答案

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

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()

关于r - mutate(across()) 使用外部函数引用当前数据帧中的其他变量而不传递第二个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68232588/

相关文章:

r - 有条件地计算 2 个日期之间每个 ID 的唯一日期数

r - 创建一个方阵,使得每个元素都等于 2^|j-k|在 R

r - 禁用 cat 命令

r - 将多个函数应用于矩阵列表并在数据框中输出答案

c - 如果有许多具有相同参数的函数,是否应该使用宏来避免多次输入参数?

javascript - 单击图像不起作用

Javascript - 为什么首先评估 bool 表达式内的函数调用?

检索给定大小 k 的 n 项的所有可能组合,并在另一列上应用函数 sum

根据前一个变量的值重命名变量

R:如何从数据框中提取列表?