R语言:按相同前缀列计算单元格占组内行总和的比例
解决方案:计算DataFrame同前缀列组的行内占比
关于group_by的说明
dplyr::group_by是用来对行做分组统计(比如按irm月份分组聚合),你的需求是按列的前缀分组做行内计算,所以group_by在这里不适用,推荐用across+starts_with的组合实现批量处理。
方案一:dplyr循环批量处理
先构造示例数据(模拟你的37列结构):
set.seed(123) df <- tibble( irm = paste0("2023", sprintf("%02d", 1:10)), # 生成trans11-trans16到trans61-trans66共36列 !!!map(paste0("trans", 1:6), ~ set_names(rpois(10, 10), paste0(.x, 1:6))) )
然后遍历每个前缀组,计算行内占比:
library(dplyr) # 遍历trans1到trans6的前缀 for (prefix in paste0("trans", 1:6)) { df <- df %>% mutate( # 选中当前前缀的所有列,计算占行内总和的比例 across(starts_with(prefix), ~ .x / rowSums(across(starts_with(prefix))), # 生成带_ratio后缀的新列,若要替换原列可删除此参数 .names = "{.col}_ratio") ) }
方案二:purrr无循环批量处理
如果偏好函数式编程风格,用purrr::reduce批量应用计算逻辑:
library(purrr) library(dplyr) prefixes <- paste0("trans", 1:6) # 定义单个前缀组的占比计算函数 calc_ratio <- function(data, prefix) { data %>% mutate(across(starts_with(prefix), ~ .x / rowSums(across(starts_with(prefix))), .names = "{.col}_ratio")) } # 依次对每个前缀组应用计算,合并结果 df_with_ratios <- prefixes %>% reduce(calc_ratio, .init = df)
方案三:基础R原生实现
不用tidyverse包的话,用基础R的字符串匹配和循环完成:
prefixes <- paste0("trans", 1:6) for (prefix in prefixes) { # 匹配当前前缀的所有列名 col_indices <- grep(paste0("^", prefix), names(df)) # 计算该行当前组的总和 row_sums <- rowSums(df[, col_indices]) # 生成占比列并添加到原数据框 df[paste0(names(df)[col_indices], "_ratio")] <- df[, col_indices] / row_sums }
内容的提问来源于stack exchange,提问作者jvalenti
相关产品推荐
相关产品推荐

