如何在R中基于类别-功能组映射批量计算数据框行求和?
当然有更高效的批量处理方案!不用一遍遍重复写代码,我们可以用几个简洁的方法搞定,甚至刚好能用上你提到的purrr包~下面给你分享几种实用的实现方式:
方法1:用dplyr + tidyr 重塑数据(直观易读)
这种方法通过数据格式的转换,自动处理所有功能组的求和,不需要手动指定任何分组:
library(dplyr) library(tidyr) # 1. 将宽格式的原数据转为长格式,保留id作为标识列 class_df_long <- class_df %>% pivot_longer(cols = -id, names_to = "class", values_to = "proportion") # 2. 关联功能组映射表,按id和功能组分组求和 fg_total <- class_df_long %>% left_join(class_fg, by = "class") %>% group_by(id, fg) %>% summarise(total = sum(proportion), .groups = "drop") %>% pivot_wider(names_from = fg, values_from = total) # 3. 将求和结果合并回原数据框 class_df_with_fg <- class_df %>% left_join(fg_total, by = "id")
方法2:用purrr 批量处理(满足你的需求)
如果你偏好purrr的函数式编程风格,可以按功能组拆分映射表,批量计算每行求和:
library(purrr) library(dplyr) # 先按功能组拆分,得到每个组对应的类别列表 fg_class_groups <- class_fg %>% group_split(fg) %>% set_names(map(., ~ .$fg[1])) %>% # 用功能组名称命名列表元素 map(~ .$class) # 批量计算每个功能组的行求和,并按列绑定到原数据框 class_df_with_fg <- class_df %>% bind_cols(map_dfc(fg_class_groups, ~ rowSums(select(class_df, all_of(.x)))))
方法3:用data.table 处理大数据(高效提速)
如果你的数据量很大,data.table的速度优势会非常明显:
library(data.table) # 转换为data.table格式 setDT(class_df) setDT(class_fg) # 长格式合并+分组求和,再转回宽格式 class_df_long <- melt(class_df, id.vars = "id", variable.name = "class", value.name = "proportion") fg_total <- class_df_long[class_fg, on = "class"][, .(total = sum(proportion)), by = .(id, fg)] fg_wide <- dcast(fg_total, id ~ fg, value.var = "total") # 合并回原数据框 class_df_with_fg <- class_df[fg_wide, on = "id"]
以上三种方法都能自动批量生成所有功能组的求和列,不用重复编写单个组的计算代码,最终得到的结果和你期望的完全一致~
内容的提问来源于stack exchange,提问作者Syzorr
相关产品推荐
相关产品推荐

