R语言中在sapply循环内用向量作为grep模式求和的问题
解决R语言中apply循环里grep匹配列名求和的问题
嘿,我来帮你搞定这个问题!首先咱们先搞清楚你出错的原因:你在sapply的匿名函数里用了grep(individuals, colnames(bcdata_clean)),这里的individuals是整个向量,而grep的pattern参数如果长度大于1,只会取第一个元素来匹配——这就是为什么你会看到那个警告,而且结果里所有列都一模一样的原因!
最优修正方案(基础R版本)
其实问题很容易解决,你只需要在匿名函数里用sapply传递给你的单个元素x(也就是individuals里的每一项),而不是整个individuals向量。另外,推荐用rowSums替代apply(..., 1, sum),它是专门为行求和设计的函数,代码更简洁,运行速度也更快,尤其是数据集大的时候。
修正后的代码如下:
# 你的individuals向量(替换成实际的内容) individuals <- c("ID1", "ID2") bcdata_total <- sapply(individuals, function(x) { # 用当前迭代的x作为匹配模式,找到对应的列索引 target_cols <- grep(x, colnames(bcdata_clean)) # 对选中的列按行求和 rowSums(bcdata_clean[, target_cols]) })
验证效果
用你给出的示例数据测试:
# 构造示例数据集 bcdata_clean <- data.frame( `ID1-4` = c(3, 2, 4), `ID1-3` = c(2, 2, 5), `ID2-5` = c(1, 3, 5), row.names = c("A", "B", "C") )
运行修正后的代码,得到的bcdata_total就是你想要的结果:
ID1 ID2 A 5 1 B 4 3 C 9 5
额外技巧(tidyverse风格)
如果你熟悉tidyverse工具链,也可以用purrr和dplyr来实现,代码可读性更强:
library(purrr) library(dplyr) bcdata_total <- map_dfc(individuals, function(x) { bcdata_clean %>% select(contains(x)) %>% # 直接筛选包含x的列 rowSums() %>% as.data.frame() %>% rename(!!x := .) # 把列名改成对应的individuals元素 })
核心要点回顾
- 每次迭代要使用
individuals的单个元素作为grep的匹配模式,也就是sapply传递的x参数。 - 优先使用
rowSums代替apply(..., 1, sum),效率更高且代码更简洁。
内容的提问来源于stack exchange,提问作者obki
相关产品推荐
相关产品推荐

