如何基于独立DataFrame实现sumproduct运算?
问题描述
我有如下包含5个数值列的数据集:
test_data <- tribble( ~one, ~two, ~three, ~four, ~five, 1, 2, 3, 4, 5, 2, 4, 6, 8, 10, 3, 6, 9, 12, 15, 4, 8, 12, 16, 20 )
以及用于加权的权重表:
multiplier <- tribble( ~step, ~pct, "one", 0, "two", 1, "three", 0, "four", 1, "five", 0 )
需要生成包含result列的结果表,result是各列按对应权重加权求和的结果,预期输出如下:
> result_df # A tibble: 4 x 6 one two three four five result <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 2 3 4 5 6 2 2 4 6 8 10 12 3 3 6 9 12 15 18 4 4 8 12 16 20 24
实际场景中有约40个列,且权重可能是0到1之间的任意值,之前尝试的代码无法得到正确结果:
test_data %>% rowwise() %>% mutate(result = prod(one:five, multiplier$pct))
也试过crossprod但不符合需求,需要dplyr风格的解决方案。
解决方案
方法1:mutate() + c_across()(推荐,适配多列场景)
先提取和数据集列顺序匹配的权重向量,再通过行内向量运算完成加权求和:
library(dplyr) # 提取权重,确保和test_data的列顺序一致 weights <- multiplier$pct[match(names(test_data), multiplier$step)] test_data %>% mutate(result = rowSums(c_across(everything()) * weights))
c_across(everything())会将每一行的所有列转换为向量,和权重向量逐元素相乘后,用rowSums快速求和,无需逐行分组,效率更高。
方法2:rowwise()显式处理行
如果需要逐行操作,可结合rowwise()和c_across()实现:
test_data %>% rowwise() %>% mutate(result = sum(c_across(everything()) * weights)) %>% ungroup() # 处理完记得取消分组,避免后续操作性能下降
方法3:矩阵乘法(大数据集高效方案)
当数据集规模较大时,矩阵乘法的运算效率最优,结合dplyr的写法如下:
test_data %>% mutate(result = as.matrix(.) %*% weights)
as.matrix(.)将数据集转换为矩阵,与权重向量做矩阵乘法后,直接生成result列。
内容的提问来源于stack exchange,提问作者J K
相关产品推荐
相关产品推荐

