R语言按变量后缀分组求和:代码修正与优化方案咨询
我来帮你解决这个问题——你现在的核心问题是用paste(collapse = '+')把变量名拼成了字符串,而不是生成能计算数值的表达式,所以mutate之后新列存的是变量名字符串,不是求和结果。下面分两部分给你解决方案:
1. 修改现有代码实现需求
你可以把拼接好的变量名字符串转换成R可执行的表达式,然后在mutate中求值。这里有两种常用方法:
方法1:用rlang的非标准求值(推荐,更符合tidyverse风格)
library(dplyr) library(rlang) # 提取变量名并拼接成字符串 end_with_t <- grep('t$', names(test), value = T) %>% paste(collapse = '+') end_with_man <- grep('[^a-z]man$', names(test), value = T) %>% paste(collapse = '+') end_with_woman <- grep('woman$', names(test), value = T) %>% paste(collapse = '+') end_with_lo65 <- grep('lo65$', names(test), value = T) %>% paste(collapse = '+') end_with_hi65 <- grep('hi65$', names(test), value = T) %>% paste(collapse = '+') # 将字符串转为表达式并求值 test2 <- test %>% mutate( t = !!parse_expr(end_with_t), man = !!parse_expr(end_with_man), woman = !!parse_expr(end_with_woman), lo65 = !!parse_expr(end_with_lo65), hi65 = !!parse_expr(end_with_hi65) )
方法2:用基础R的eval(parse)
如果你不想额外加载rlang包,可以用基础R的组合:
test2 <- test %>% mutate( t = eval(parse(text = end_with_t)), man = eval(parse(text = end_with_man)), woman = eval(parse(text = end_with_woman)), lo65 = eval(parse(text = end_with_lo65)), hi65 = eval(parse(text = end_with_hi65)) )
运行后你会看到每个新列的值都是3(因为测试数据里每个后缀对应3个值为1的变量),这就是你要的数值求和结果。
2. 更优的实现方法
其实完全不需要先用grep提取再拼接字符串,直接用dplyr的across()结合matches()函数,就能直接对匹配的变量求和,代码更简洁、可读性更高,还避免了字符串拼接的麻烦:
简洁版(推荐)
library(dplyr) test2 <- test %>% mutate( t = rowSums(across(matches('t$'))), man = rowSums(across(matches('[^a-z]man$'))), woman = rowSums(across(matches('woman$'))), lo65 = rowSums(across(matches('lo65$'))), hi65 = rowSums(across(matches('hi65$'))) )
批量处理版(适合后缀很多的场景)
如果需要处理的后缀数量很多,重复写代码太麻烦,可以用purrr批量生成新列:
library(dplyr) library(purrr) # 定义后缀规则和对应的新列名 suffix_rules <- c('t$', '[^a-z]man$', 'woman$', 'lo65$', 'hi65$') new_col_names <- c('t', 'man', 'woman', 'lo65', 'hi65') # 批量生成求和列 test2 <- test %>% bind_cols( map2_dfc(suffix_rules, new_col_names, ~ { test %>% transmute(!!.y := rowSums(across(matches(.x)))) }) )
这种方法扩展性很强,后续要加新的后缀规则,只需要在向量里添加即可。
内容的提问来源于stack exchange,提问作者zhiwei li
相关产品推荐
相关产品推荐

