如何将每项病原体检测占一行的 dataframe 转换为每个受检个体占一行?
按 sampleID 分组,用 any() 判断每组是否至少有一项检测为阳性,就能将数据汇总为每只啮齿动物一行。将判断结果转为整数后,pathPresence 中的 1 表示至少一项阳性,0 表示全部阴性。
分组只依据 sampleID,数据的排序和同一个体的记录是否连续都不影响汇总结果。
按 sampleID 汇总
假设原始数据框为 df,检测结果列为 result,用 1 表示阳性、0 表示阴性,且没有缺失值:
library(dplyr)
individual_df <- df %>%
group_by(sampleID) %>%
summarise(
pathPresence = as.integer(any(result == 1)),
.groups = "drop"
)
使用时,将 result 替换为实际的检测结果列名。
group_by(sampleID) 将同一个体的记录分为一组,any(result == 1) 检查组内是否有阳性结果,返回 TRUE 或 FALSE。as.integer() 再将两者分别转为 1 和 0。summarise() 为每组生成一行,.groups = "drop" 移除汇总结果的分组属性。
如果数据中有 60 个不同且有效的 sampleID,汇总结果就有 60 行。
一个简化示例
以每只个体三项检测为例:
df <- data.frame(
sampleID = c("R01", "R01", "R01", "R02", "R02", "R02"),
result = c(0, 1, 0, 0, 0, 0)
)
individual_df <- df %>%
group_by(sampleID) %>%
summarise(
pathPresence = as.integer(any(result == 1)),
.groups = "drop"
)
结果为:
# A tibble: 2 × 2
sampleID pathPresence
<chr> <int>
1 R01 1
2 R02 0
R01 有一项阳性,记为 1;R02 全部阴性,记为 0。每只个体有 18 项检测时,也使用同样的代码。
根据实际数据调整阳性条件
如果检测结果用 "Positive" 和 "Negative" 等字符串表示,将判断条件改为:
pathPresence = as.integer(any(result == "Positive"))
如果结果列是逻辑值,且 TRUE 表示阳性,可以写成:
pathPresence = as.integer(any(result))
使用前要确认结果的实际编码,包括字符串的大小写和空格。不要直接用 as.integer(result) 将字符列或因子列转为整数来判断阳性。
缺失值需要单独约定
默认情况下,any() 对缺失值的处理如下:
- 只要有一项明确为阳性,即使同时有
NA,也返回TRUE。 - 没有阳性,但存在
NA,返回NA。 - 所有检测均明确为阴性,返回
FALSE。
因此,检测结果有缺失时,上面代码生成的 pathPresence 可能为 NA,表示尚不能确定,以此与全部阴性区分。
如果只需要判断“已有记录中是否发现阳性”,可以忽略缺失值:
individual_df <- df %>%
group_by(sampleID) %>%
summarise(
pathPresence = as.integer(any(result == 1, na.rm = TRUE)),
.groups = "drop"
)
此时,0 表示“未发现阳性记录”。即使某只个体的检测结果全部为 NA,也会得到 0,不能据此认定其 18 项检测全部阴性。
汇总前检查记录数
用以下代码检查每个 sampleID 是否恰好有 18 条记录:
df %>%
count(sampleID, name = "n_tests") %>%
filter(n_tests != 18)
如果 sampleID 完整有效,且代码返回零行,说明每只个体都有 18 条记录。不过,记录数正确并不能证明 18 种病原体各检测了一次。如果有病原体标识列,还应检查是否存在重复或遗漏。
还要确认 sampleID 没有缺失。缺失的 ID 会归入同一组,无法区分对应的个体。
汇总结果只保留 sampleID 和 pathPresence。如果还需要性别、采样地点等个体信息,应先确认这些字段在同一个体的各条记录中一致,再加入汇总结果。
备注:内容仅供参考。
