在R中基于文本列指定列范围跨行求和报错求助
问题描述
需求:基于文本列col_range中指定的列范围,为每行创建新列存储对应范围的求和结果。
尝试的代码:
d = data.frame(index_id = c("a1232","c198", "s345","2ert", "e234","e567"), yr_ref = c(2023,2024,2025,2024,2027,NA), temp2023 = c(2000,5000,2300,2000,1000,200), temp2024 = c(3000,3000,3000,0,0,200), temp2025 = c(2000,3000,0,800,8000,200), temp2026 = c(300,200,1000,0,0,200), temp2027= c(1300,1200,100,10,10,200), col_range = c("temp2023:temp2023","temp2023:temp2024","temp2023:temp2025","temp2023:temp2024","temp2023:temp2027",NA)) d= d %>% mutate(temp_total= ifelse(!is.na(yr_ref), sum(c_across(col_range)),NA))
报错信息:
Error in `mutate()`: ℹ In argument: `temp_total = ifelse(!is.na(yr_ref), sum(c_across(col_range)), NA)`. Caused by error in `sum()`: ! invalid 'type' (character) of argument Run `rlang::last_trace()` to see where the error occurred.
报错原因
c_across()无法直接识别字符串格式的列范围(如"temp2023:temp2024"),它需要的是列名符号或tidy选择器,而非字符向量。sum()默认是整列聚合计算,而非逐行处理;同时ifelse的向量化逻辑和逐行处理需求不匹配,导致类型错误。
解决方案
方法一:用rowwise()逐行解析计算
开启逐行处理模式,结合rlang工具解析字符串格式的列范围并执行求和:
library(dplyr) library(rlang) d <- d %>% rowwise() %>% mutate(temp_total = if (!is.na(yr_ref) && !is.na(col_range)) { eval(parse_expr(paste0("sum(", col_range, ")"))) } else { NA_real_ }) %>% ungroup()
方法二:用pmap()逐行处理
借助purrr的pmap函数实现逐行逻辑,更灵活可控:
library(dplyr) library(purrr) library(stringr) d <- d %>% mutate(temp_total = pmap_dbl(., function(yr_ref, col_range, ...) { if (is.na(yr_ref) || is.na(col_range)) { return(NA_real_) } # 拆分列范围字符串,获取起始和结束列名 col_names <- str_split(col_range, ":")[[1]] # 筛选对应列并求和 sum(select(., all_of(col_names)), na.rm = TRUE) }))
处理后temp_total列会正确输出每行指定列范围的求和结果,例如第一行结果为2000,第二行为5000+3000=8000,以此类推。
内容的提问来源于stack exchange,提问作者krishthw
相关产品推荐
相关产品推荐

