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

如何在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)
原代码问题说明
  1. 函数定义位置错误:在mutate中直接定义函数不符合语法,mutate需要的是计算表达式,而非完整的函数定义
  2. 未累加结果:循环中每次用z <- y1*y2会覆盖之前的结果,应该初始化z=0后用z <- z + y1*y2累加
  3. 变量引用错误:get(paste0(x,'$','a_',i))中x未定义,且在dplyr上下文中不需要用$引用列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 03:55:18