如何在R语言dplyr中实现对应变量相乘后求和生成新变量?
问题描述
需要将数据框中对应变量相乘后求和(a_1*b_1 + a_2*b_2 + ...),已创建示例数据框如下:
library(dplyr) set.seed(123) # 固定随机种子,保证结果可复现 (df <- tibble( a_1 = sample(1:5), a_2 = sample(1:5), b_1 = sample(1:5), b_2 = sample(1:5), desired_output = (a_1*b_1 + a_2*b_2) ))
输出结果:
# A tibble: 5 × 5 a_1 a_2 b_1 b_2 desired_output <int> <int> <int> <int> <int> 1 3 5 2 4 26 2 2 4 5 1 14 3 5 3 1 3 14 4 1 1 3 5 8 5 4 2 4 2 20
用户尝试自定义函数实现时出现错误,以下是几种正确的实现方式:
正确实现方法
方法1:直接计算(列数固定时使用)
如果只有a_1/a_2和b_1/b_2这类固定数量的对应列,直接写出计算式最直观:
df %>% mutate(calculated_output = a_1*b_1 + a_2*b_2)
方法2:通用灵活写法(支持任意数量a/b列)
如果后续会新增a_3/b_3、a_4/b_4等列,用通用方法可以避免修改代码:
方式一:用dplyr的rowwise+c_across
df %>% rowwise() %>% mutate(calculated_output = sum(c_across(starts_with("a_")) * c_across(starts_with("b_")))) %>% ungroup()
starts_with("a_")匹配所有以a_开头的列,c_across将这些列按行转为向量- 对应位置的a列和b列向量相乘后求和,得到每行的结果
方式二:用purrr的pmap_dbl
library(dplyr) library(purrr) df %>% mutate(calculated_output = pmap_dbl(., function(...) { args <- list(...) a_cols <- args[grepl("^a_", names(args))] b_cols <- args[grepl("^b_", names(args))] sum(unlist(a_cols) * unlist(b_cols)) }))
pmap_dbl逐行处理数据框,每行的所有列作为参数传入匿名函数- 通过正则匹配筛选出a列和b列,转为向量后相乘求和
方法3:基础R实现(无需tidyverse包)
如果不使用tidyverse系列包,用基础R的矩阵操作也能实现:
# 筛选a列和b列 a_cols <- df[, grepl("^a_", names(df))] b_cols <- df[, grepl("^b_", names(df))] # 逐行计算对应乘积的和 df$calculated_output <- rowSums(a_cols * b_cols)
原代码问题说明
- 函数定义位置错误:在
mutate中直接定义函数不符合语法,mutate需要的是计算表达式,而非完整的函数定义 - 未累加结果:循环中每次用
z <- y1*y2会覆盖之前的结果,应该初始化z=0后用z <- z + y1*y2累加 - 变量引用错误:
get(paste0(x,'$','a_',i))中x未定义,且在dplyr上下文中不需要用$引用列
内容的提问来源于stack exchange,提问作者Pete
相关产品推荐
相关产品推荐

