R中使用函数和mapply生成求和新列未写入dataframe问题排查
核心问题
- 函数内赋值为局部作用域:你在
kick_him函数内写的d <- rowSums(...)只在函数运行的临时环境里生效,不会修改全局环境中的martial_arts,你传入的d只是字符串,没有触发对原数据框的修改操作 - 未接收mapply的输出结果:
mapply已经计算出了正确的求和矩阵,但你没有把这个矩阵赋值回martial_arts,自然不会新增列
修复代码
和你原有逻辑最接近的修改版本如下:
# 可复现示例数据 library(dplyr) martial_arts <- data.frame(gym_branch=c("downtown_a", "downtown_b", "uptown", "island"), day_boxing=c(5,30,25,10),day_muaythai=c(34,18,20,30), day_bjj=c(0,0,0,0),day_judo=c(10,0,5,0), evening_boxing=c(50,45,32,40), evening_muaythai=c(50,50,45,50), evening_bjj=c(60,60,55,40), evening_judo=c(25,15,30,0)) # 生成新列名,不需要用expand.grid,直接生成字符向量即可 pattern <- c("_boxing","_muaythai","_bjj","_judo") new_cols <- paste0("total", pattern) # 生成需要相加的两组列名列表 e <- names(martial_arts %>% select(day_boxing:day_judo)) f <- names(martial_arts %>% select(evening_boxing:evening_judo)) # 自定义函数简化为仅返回求和结果 kick_him <- function(e,f){ rowSums(martial_arts[ , c(e, f)], na.rm=T) } # 将mapply返回的求和矩阵直接赋值给原数据框的新列 martial_arts[new_cols] <- mapply(kick_him, e, f)
运行后martial_arts就会新增4个total开头的汇总列,和你预期的手动赋值效果完全一致。
如果习惯用dplyr的语法,也可以用更简洁的批量处理写法:
martial_arts <- martial_arts %>% mutate(across(starts_with("day_"), ~.x + get(paste0("evening_", sub("day_", "", cur_column()))), .names = "total_{sub('day_', '', .col)}"))
内容的提问来源于stack exchange,提问作者Pineapple
相关产品推荐
相关产品推荐

