R语言按每n行分组求和后同列单元格除以对应组和的实现
解决方案
你可以根据你的数据规模选择以下两种方法,都支持自动适配所有数值列,无需手动指定50个列名,非数值列(如国家标识)会原样保留:
方法1:dplyr 实现(易读易写,适合中小数据)
代码逻辑简单易维护,常规数据量下运行速度足够:
library(dplyr) # 分组大小,实际使用替换为1100 n <- 4 df_result <- df %>% # 按行顺序每n行划分为一个分组 group_by(group_id = ceiling(row_number() / n)) %>% # 对所有数值列,每个值除以该列的分组求和结果 mutate(across(where(is.numeric), ~ .x / sum(.x, na.rm = TRUE))) %>% ungroup() %>% # 不需要分组ID可删除该行 select(-group_id)
方法2:data.table 实现(高性能,适合大数据)
如果你的数据量较大(十万行以上),推荐用data.table实现,运行效率比dplyr高5~10倍:
library(data.table) # 分组大小,实际使用替换为1100 n <- 4 # 转换为data.table格式 setDT(df) # 生成分组ID df[, group_id := (.I - 1) %/% n + 1] # 识别所有数值列 num_cols <- setdiff(names(df)[sapply(df, is.numeric)], "group_id") # 对所有数值列按组做归一化 df[, (num_cols) := lapply(.SD, function(x) x / sum(x, na.rm = TRUE)), by = group_id, .SDcols = num_cols] # 不需要分组ID可删除该行 df[, group_id := NULL] # 如果需要转回普通dataframe格式,运行以下代码 # setDF(df)
两种方法得到的结果和你给出的预期示例完全一致,na.rm = TRUE参数可以避免分组内存在缺失值时求和得到NA的问题,如果你确认数据无缺失可以去掉该参数进一步提升速度。
内容的提问来源于stack exchange,提问作者Emil Krabbe
相关产品推荐
相关产品推荐

