在R中基于df1分类条件对df2行数据求和生成df3
嘿,这个需求在R里完全不用像Excel那样写复杂的嵌套IF,有好几套简洁高效的实现方案,我结合你给的示例数据拆解下👇
首先先把示例数据准备好:
# 示例数据 df1 <- data.frame(a = c(2, 2, 1), b = c(3, 2, 3), c = c(1, 1, 2), d = c(3, 3, 1)) df2 <- data.frame(a = c(0.1, 0.1, 0.2), b = c(0.3, 0.4, 0.6), c = c(0.2, 0.3, 0.5), d = c(0.1, 0.5, 0.6))
方法1:基础R向量化操作(最推荐,高效简洁)
这是我最常用的方法,完全是向量化运算,没有循环,对于你220行80列的数据集来说,速度快到离谱,代码也超短:
df3 <- data.frame( X1 = rowSums(df2 * (df1 == 1)), # 对每行df1中等于1的位置,求和df2对应值 X2 = rowSums(df2 * (df1 == 2)), X3 = rowSums(df2 * (df1 == 3)) ) # 查看结果 df3 # X1 X2 X3 # 1 0.2 0.1 0.4 # 2 0.3 0.5 0.5 # 3 0.8 0.5 0.6
逻辑解释:df1 == 1会生成一个和df1同大小的逻辑矩阵,TRUE对应df1里值为1的位置;和df2相乘后,逻辑值会自动转成1/0,只有对应位置的df2数值会保留,其他变为0;最后用rowSums对每行求和,就得到了每个分类的总收益率。
方法2:逐行循环处理(逻辑直观,适合新手理解)
如果你想更清晰地看到每行的处理逻辑,可以用apply逐行操作,虽然速度比向量化慢一点,但220行的规模完全没问题:
# 定义一个函数,处理单行的分类求和 calculate_row_total <- function(df1_row, df2_row) { c( X1 = sum(df2_row[df1_row == 1]), X2 = sum(df2_row[df1_row == 2]), X3 = sum(df2_row[df1_row == 3]) ) } # 对df1的每一行应用函数,转置后转成data frame df3 <- t(apply(df1, 1, function(x) calculate_row_total(x, df2[rownames(df1) == rownames(df2), ]))) df3 <- as.data.frame(df3)
这个方法的逻辑和Excel里逐行计算的思路一致,只是用代码自动化了重复操作。
方法3:Tidyverse风格(适配数据清洗流程)
如果你平时习惯用dplyr/tidyr这类工具做数据处理,可以用长格式转换的方式实现,好处是后续如果增加分类(比如新增4类),不需要修改代码就能自动适配:
library(tidyverse) # 先把两个df转成长格式,合并后按行和分类求和,再转回宽格式 df1_long <- df1 %>% mutate(row_id = row_number()) %>% pivot_longer(-row_id, names_to = "var", values_to = "category") df2_long <- df2 %>% mutate(row_id = row_number()) %>% pivot_longer(-row_id, names_to = "var", values_to = "return") df3 <- inner_join(df1_long, df2_long, by = c("row_id", "var")) %>% group_by(row_id, category) %>% summarise(total_return = sum(return), .groups = "drop") %>% pivot_wider(names_from = category, values_from = total_return, names_prefix = "X") %>% select(-row_id)
不管用哪种方法,最终生成的df3都是你需要的220行3列的数据集,完美对应三类投资组合的收益率总和~
内容的提问来源于stack exchange,提问作者Mataunited18
相关产品推荐
相关产品推荐

