You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用dplyr的mutate和across在R中实现多列对应乘积?

解决dplyr中mutate+across计算关联列乘积的报错问题

需求说明

现有两个数据框dft0和dft1,二者共享id列用于匹配观测;dft0中的列(如x/y/z)对应dft1中前缀为b_的列(如b_x/b_y/b_z)。需要用dplyr的mutate和across函数,计算每对对应列的乘积,生成名为p_列名的新列。

示例数据

library(dplyr)

dft0 <- data.frame(id = 101:103, x   = 1:3,   y   = 4:6,   z   = 7:9)
dft1 <- data.frame(id = 101:103, b_x = 10:12, b_y = 13:15, b_z = 16:18)

报错代码及信息

尝试的代码:

vs   <- c('x', 'y', 'z')
dfts <- full_join(dft0, dft1, by = c('id')) %>%
  mutate(., across(vs, .fn = ~ .x * get(paste0('b_', .x)), .names = 'p_{.col}'))

报错信息:

Error in `mutate_cols()`:
! Problem with `mutate()` input `..1`.
i `..1 = across(...)`.
x first argument has length > 1
Caused by error in `get()`:
! first argument has length > 1
Run `rlang::last_error()` to see where the error occurred.

报错原因

报错核心是across的函数中,.x指代的是当前列的数值向量,而非列名。用paste0('b_', .x)会把列的每个数值都拼上b_,生成一个长度大于1的向量,而get()只能接受单个字符串作为参数,因此触发错误。

修正方案

需要获取当前遍历的列名而非列值,这里可以用cur_column()函数来获取当前列的名称,再拼接对应关联列的名称:

方案一:使用cur_column() + get()

vs   <- c('x', 'y', 'z')
dfts <- full_join(dft0, dft1, by = c('id')) %>%
  mutate(across(vs, ~ .x * get(paste0('b_', cur_column())), .names = 'p_{.col}'))

方案二:使用cur_column() + .data代词(更推荐,可读性更强)

vs   <- c('x', 'y', 'z')
dfts <- full_join(dft0, dft1, by = c('id')) %>%
  mutate(across(vs, ~ .x * .data[[paste0('b_', cur_column())]], .names = 'p_{.col}'))

运行结果

执行修正后的代码后,dfts会新增p_x/p_y/p_z三列,对应每对列的乘积:

> dfts
   id x y z b_x b_y b_z p_x p_y p_z
1 101 1 4 7  10  13  16  10  52 112
2 102 2 5 8  11  14  17  22  70 136
3 103 3 6 9  12  15  18  36  90 162

内容的提问来源于stack exchange,提问作者DOS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:28:20