You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R语言中计算分组数据占列总计的百分比

问题:计算分组月度数据占当月总计的百分比

原始数据

分组1990年5月1990年6月1990年7月
1581552465
2193184176
3207177165
总计981913806

目标结果

需要计算每个分组的月度数据占对应月份总计的百分比,保留两位小数,得到如下表格:

分组1990年5月1990年6月1990年7月
10.590.600.58
20.190.210.22
30.210.190.20
总计111

出错的代码

df <- data.frame(group=c('1','2','3','Total'),may_1990=c(581,193,207,981),jun_1990=c(552,184,177,913),jul_1990=c(465,176,165,806))

total <- df %>% slice_tail(n = 1)
z <- df %>% rowwise() %>% mutate(across(where(is.numeric), ~ .x/total[-1]))

问题分析

原代码存在两个核心问题:

  1. 误用rowwise():across默认按列批量处理,逐行操作不仅降低效率,还会导致逻辑偏差;
  2. 除法对象错误:total[-1]是完整数据框,直接做除法会让每个数值列与整个总计数据框做广播运算,而非对应列的单个总计值,结果完全不符合预期。

修正方案

方法一:提取总计向量,按列匹配计算(适合多列场景)

library(dplyr)

df <- data.frame(
  group=c('1','2','3','Total'),
  may_1990=c(581,193,207,981),
  jun_1990=c(552,184,177,913),
  jul_1990=c(465,176,165,806)
)

# 提取总计行的数值并转为命名向量,确保列名匹配
total_vals <- df %>% slice_tail(n=1) %>% select(where(is.numeric)) %>% unlist()

# 对每个数值列,除以对应月份的总计值
z <- df %>% mutate(across(where(is.numeric), ~ .x / total_vals[cur_column()]))

# 保留两位小数,匹配目标格式
z <- z %>% mutate(across(where(is.numeric), ~ round(.x, 2)))

方法二:直接引用对应列的总计值(适合列数较少场景)

library(dplyr)

df <- data.frame(
  group=c('1','2','3','Total'),
  may_1990=c(581,193,207,981),
  jun_1990=c(552,184,177,913),
  jul_1990=c(465,176,165,806)
)

z <- df %>% 
  mutate(
    may_1990 = may_1990 / may_1990[group == 'Total'],
    jun_1990 = jun_1990 / jun_1990[group == 'Total'],
    jul_1990 = jul_1990 / jul_1990[group == 'Total']
  ) %>% 
  mutate(across(where(is.numeric), ~ round(.x, 2)))

两种方法都能得到符合预期的结果,方法一更灵活,适合列数较多的数据集。

内容的提问来源于stack exchange,提问作者Mar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 23:25:36