使用dplyr的select和mutate在循环中为数据框新增年度汇总变量
解决年度汇总列的添加问题
嗨,我来帮你搞定这个需求!你的思路方向是对的,但代码里有几个小细节没处理好导致报错,我们先拆解问题,再给出几种可行的解决方案~
你的代码存在的问题
contains("i")里的i被当成了字符串"i",而不是循环中的年份变量,应该用contains(as.character(i))来匹配对应年份的列mutate(varname = sum())中的sum()默认是对整个列求和,不是按行计算;同时varname作为变量名,直接写会被当成字符串"varname",无法生成动态的列名assign(df$varname, ...)的用法有误,assign是用来创建全局变量的,不是给数据框添加列,正确的方式是直接给数据框的列赋值,比如df[[varname]] <- ...
解决方案1:用dplyr + purrr(简洁高效)
这种方法适合习惯tidyverse语法的用户,代码更简洁易读:
library(dplyr) library(purrr) # 定义需要汇总的年份 target_years <- 2012:2014 # 遍历年份,生成年度汇总列并合并到原数据框 df <- target_years %>% map_dfc(function(year) { # 筛选对应年份的列,按行求和,并重命名列 df %>% select(contains(as.character(year))) %>% rowSums(na.rm = TRUE) %>% set_names(paste0("TotalYr", year)) }) %>% # 将汇总列合并到原数据框的右侧 bind_cols(df, .)
解决方案2:用Base R(适合初学者理解)
如果还不熟悉tidyverse,用Base R的循环也能轻松实现,逻辑更直观:
# 定义需要汇总的年份 target_years <- 2012:2014 for (year in target_years) { # 把年份转为字符串,方便匹配列名 year_str <- as.character(year) # 构造新列的名称 new_col_name <- paste0("TotalYr", year) # 筛选出所有包含该年份的列,计算每行的和 df[[new_col_name]] <- rowSums(df[, grepl(year_str, colnames(df))], na.rm = TRUE) }
验证结果
运行完上面任意一段代码后,你会看到数据框新增了TotalYr2012、TotalYr2013、TotalYr2014列,其中TotalYr2012的结果正好是你想要的c(4, 9, 12, 15),完全符合需求~
内容的提问来源于stack exchange,提问作者LauraDR
相关产品推荐
相关产品推荐

