R语言按年份分组标准化含ABC/XYZ后缀列的实现问题
解决R语言分组生成Z分数列的问题
看起来你在分组标准化列的时候遇到了两个核心问题:一是select()会丢掉你需要保留的原始列(比如VARTY、VARDCE),二是mutate(funs(scale))的语法已经过时,在新版dplyr中需要用across()来处理多列批量操作。下面是修正后的完整解决方案:
核心解决代码
library(dplyr) # 按Year分组,对后缀为ABC/XYZ的列生成Z分数列,保留所有原始列 DF.New <- DF %>% group_by(Year) %>% mutate( across( .cols = ends_with(c("ABC", "XYZ")), .fns = ~scale(.)[,1], # 提取scale返回矩阵的数值列,避免生成矩阵格式的新列 .names = "{col}ZScore" ) ) %>% ungroup() # 取消分组,属于推荐的好习惯
关键细节说明
- 列选择逻辑优化:用
ends_with(c("ABC", "XYZ"))替代contains(),因为你明确要匹配后缀为ABC或XYZ的列,contains()会匹配任何位置包含这些字符串的列,可能不符合你的精准需求。 - across()的用法:新版dplyr中
across()是处理多列操作的标准工具,参数作用如下:.cols:指定需要处理的目标列范围.fns:对列应用的函数,这里~scale(.)[,1]是因为scale()默认返回矩阵,我们需要提取数值向量作为常规数据框列.names:定义新列的命名规则,{col}会自动替换为原列名,比如Var1ABC会生成Var1ABCZScore
- 保留原始列:全程没有使用
select(),所以VARTY、VARDCE、Year以及原始的ABC/XYZ列都会完整保留在结果中,和你期望的输出结构完全一致。
效果验证
用你提供的样例数据运行代码后,会生成包含所有原始列和对应分组Z分数列的新数据框,比如每一行的Var1ABCZScore都会基于该行所属Year分组的Var1ABC列计算标准化值,完全满足分组计算的要求。
内容的提问来源于stack exchange,提问作者JeffB
相关产品推荐
相关产品推荐

