通过for each遍历变量名统计受试者特定细菌检出总次数
原有代码核心问题
- 语法错误:R的
dplyr::mutate中不支持直接用coli[i] = ...这种下标方式动态生成变量名,也无法识别sample[i]_[j]这种拼接格式的变量名,运行会直接报错 - 逻辑错误:KPN的统计代码写在了内层j循环外面,只有当j等于3时才会执行,只会统计每个采样的第3个细菌检出位的KPN结果,漏掉前两个位置的结果
- 函数使用错误:
sum默认对整列所有值求和,直接调用得到的是所有受试者的总检出次数,不是单受试者的个人累计次数 - 语法遗漏:第二段循环代码的括号、管道符顺序都存在错漏,无法正常运行
最优实现方案
不需要嵌套循环,用tidyverse的行计算逻辑就能快速实现需求,代码简洁不容易出错:
library(tidyverse) data_clean <- data %>% rowwise() %>% # 按行计算,保证统计维度是单受试者 mutate( # 匹配所有sample开头的变量,统计COLI检出次数 nb_coli = sum(c_across(starts_with("sample")) == "COLI", na.rm = TRUE), # 统计KPN检出次数 nb_kpn = sum(c_across(starts_with("sample")) == "KPN", na.rm = TRUE) ) %>% ungroup() # 取消行分组,避免后续操作出现不符合预期的问题
如果需要用循环逻辑实现,可参考如下修正后的代码:
# 初始化计数列 data$nb_coli <- 0 data$nb_kpn <- 0 for (i in 1:12) { for (j in 1:3) { # 动态拼接变量名 cur_col <- paste0("sample", i, "_", j) # 累加计数 data$nb_coli <- data$nb_coli + ifelse(data[[cur_col]] == "COLI", 1, 0) data$nb_kpn <- data$nb_kpn + ifelse(data[[cur_col]] == "KPN", 1, 0) } }
补充说明
代码中添加了na.rm = TRUE参数,就算样本列存在缺失值也不会报错,会自动跳过空值统计。如果需要统计其他细菌,只要修改判断条件里的细菌缩写即可复用代码。
内容的提问来源于stack exchange,提问作者Florence
相关产品推荐
相关产品推荐

