使用dplyr按国家总计值对指定数据列执行除法运算
用dplyr实现按国家标准化列值
没问题,用dplyr来实现这个按国家分组、将指定列值除以对应组总计的操作非常简洁,我给你分步拆解一下:
1. 先构造示例数据框
首先我们先把你提供的数据集转换成可运行的R代码:
library(dplyr) df <- tibble( Setting = rep("Rural", 6), q02_id = c(11900006, 11900031, 11900033, 11900053, 11900114, 11900446), c_school = c(0, 10, 0, 0, 3, 0), c_home = c(5, 5, 3, 7, 6, 6), c_work = c(3, 0, 0, 2, 0, 0), c_transport = c(1, 0, 0, 0, 0, 0), c_leisure = c(1, 0, 3, 0, 0, 0), Country = c("Vietnam", "China", "Vietnam", "Vietnam", "Malaysia", "Vietnam") )
2. 核心标准化操作
使用dplyr的group_by() + mutate(across())组合就能轻松搞定:
df_normalized <- df %>% # 按国家分组,后续计算都在组内进行 group_by(Country) %>% # 批量处理指定列:每个值除以该列在当前国家组的总和 mutate(across( .cols = c(c_school, c_home, c_work, c_transport, c_leisure), .fns = ~ .x / sum(.x, na.rm = TRUE) )) %>% # 取消分组,避免后续操作受分组状态影响 ungroup()
3. 处理总和为0的特殊情况
注意如果某国某列的总和为0(比如越南的c_school列总和是0),直接除以0会得到Inf或NaN。如果需要避免这种情况,可以给函数加个判断,让总和为0时返回0:
df_normalized <- df %>% group_by(Country) %>% mutate(across( c(c_school, c_home, c_work, c_transport, c_leisure), ~ ifelse(sum(.x, na.rm = TRUE) == 0, 0, .x / sum(.x, na.rm = TRUE)) )) %>% ungroup()
结果示例
运行后你会看到:
- 中国组的
c_school值变成1(10/10),c_home值变成1(5/5),其他列因为总和为0(处理后)返回0 - 马来西亚组的
c_school是1(3/3),c_home是1(6/6),其他列返回0 - 越南组的各列会按组内总和进行比例转换,比如
c_home的总和是5+3+7+6=21,对应行的值会变成5/21、3/21、7/21、6/21
内容的提问来源于stack exchange,提问作者user438383
相关产品推荐
相关产品推荐

