0. 背景说明
前面我们讲了如何在回归分析前处理低于检测限(LOD)的数据,一种是0值替换成每列/每行的最小正值,一种是将所有低于LOD的值替换为该值对应的物质LOD/
2
\sqrt 2
2,当然还有其他类似的方法。参考J Expo Sci Environ Epidemiol (2022).上的文献处理低于LOD的方法
当然,我们在处理之前需要看看这些暴露物的检出率
检出率 =
暴露物浓度
>
L
O
D
的样本数
样本总数
\frac{暴露物浓度>LOD的样本数}{样本总数}
样本总数暴露物浓度>LOD的样本数 * 100%
如果检出率比较低,视后面分析的需要删除一些暴露物。例如检出率低于75%。
下面主要记录一下如何将LOD低于75%的方法。
另外有时候可能存在NA的情况,又如何进行处理?
示例数据
##示例数据,创建一个8列8行的数据框,即8个暴露物和8个生物样本
set.seed(666)
df <- runif(64,min=0,max = 100)
dim(df) <- c(8,8)
df <- data.frame(df)
df
X1 X2 X3 X4 X5 X6 X7 X8
#1 77.43685 1.331584 3.654720 80.638553 80.46367 24.44375 51.219426 14.397736
#2 19.72242 25.994613 89.163741 26.668568 50.88974 53.09707 98.924666 89.107996
#3 97.80138 77.589308 48.323641 4.270205 63.49154 11.83959 6.913359 8.963612
#4 20.13274 1.637905 46.666453 61.217452 49.42517 98.33834 8.462063 3.773272
#5 36.12444 9.574478 98.422408 55.334840 28.01309 89.77528 12.994557 77.487436
#6 74.26119 14.216354 60.134555 85.350077 90.87104 73.85738 74.613202 81.206388
#7 97.87284 21.112624 3.834435 46.977854 78.41162 37.73107 3.887918 26.060255
#8 49.81137 81.125644 14.149569 39.761656 55.89970 60.61688 68.563542 65.159500
##假定的检出限
LOD <- c(5,10,15,20,25,30,35,40)
1. 删除检出率低于75%的暴露物
1.1 列代表8个暴露物,行代表8个生物样本
每列中样本检出率
#dr---Detection rate
dr <- c() ##新建一个空向量
for(q in c(1:8)){
c <- data.frame(df[,q])
out <- colSums(c >= LOD[q])/nrow(df)
dr <- append(dr,out)
} ##计算8个暴露物的检出率
dr
#df...q. df...q. df...q. df...q. df...q. df...q. df...q. df...q.
# 1.000 0.625 0.625 0.875 1.000 0.750 0.500 0.500
接下来我们就要根据这个检出率来提取检出率高的暴露物了
df1 <- df[,which(dr >= 0.75)] ##提取检出率大于等于75%的暴露列
df1
# X1 X4 X5 X6
#1 77.43685 80.638553 80.46367 24.44375
#2 19.72242 26.668568 50.88974 53.09707
#3 97.80138 4.270205 63.49154 11.83959
#4 20.13274 61.217452 49.42517 98.33834
#5 36.12444 55.334840 28.01309 89.77528
#6 74.26119 85.350077 90.87104 73.85738
#7 97.87284 46.977854 78.41162 37.73107
#8 49.81137 39.761656 55.89970 60.61688
这个用到了which()这个函数,这个可以对向量中的元素进行索引
顺带提几个向量的操作命令
x <- c(1,2,3,5,8,5)
which(x==5)
#[1] 4 6 ##元素5在x向量中的位置是第四和六
length(x) ##计算向量x中元素的数目
# [1] 6
x <- append(x,3) ##append()可以给向量添加元素
#[1] 1 2 3 5 8 5 3
这里附上几个向量操作的帖子
R语言使用which.min函数查看向量中最小值对应的索引位置
R语言笔记二:向量、向量索引及其运算
R语言向量vector数据类型元素索引、访问:使用length函数计算向量的长度、元素个数
1.2 行代表8个暴露物,列代表8个生物样本
这种情况处理都是一样的,t一下就可以了,也就是把数据转置一下,后面都是一模一样的,代码都不需要变。
df <- t(df)
df
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#X1 77.436849 19.72242 97.801384 20.132735 36.124443 74.26119 97.872844 49.81137
#X2 1.331584 25.99461 77.589308 1.637905 9.574478 14.21635 21.112624 81.12564
#X3 3.654720 89.16374 48.323641 46.666453 98.422408 60.13455 3.834435 14.14957
#X4 80.638553 26.66857 4.270205 61.217452 55.334840 85.35008 46.977854 39.76166
#X5 80.463673 50.88974 63.491535 49.425172 28.013090 90.87104 78.411616 55.89970
#X6 24.443749 53.09707 11.839594 98.338343 89.775284 73.85738 37.731070 60.61688
#X7 51.219426 98.92467 6.913359 8.462063 12.994557 74.61320 3.887918 68.56354
#X8 14.397736 89.10800 8.963612 3.773272 77.487436 81.20639 26.060255 65.15950
2. 一些特殊情况可以简化代码
2.1. 所有物质的LOD是同一个值
假设我们分析的非靶代谢组学数据,一般情况下分析之前需要删除强度小于10000的代谢特征
下面用一行代码来处理,示例数据还是df,这里lod我们假设是20
lod <- 20
df2 <- df[,colSums(df >= lod)/nrow(df) >= 0.75]
df2
# X1 X4 X5 X6
#1 77.43685 80.638553 80.46367 24.44375
#2 19.72242 26.668568 50.88974 53.09707
#3 97.80138 4.270205 63.49154 11.83959
#4 20.13274 61.217452 49.42517 98.33834
#5 36.12444 55.334840 28.01309 89.77528
#6 74.26119 85.350077 90.87104 73.85738
#7 97.87284 46.977854 78.41162 37.73107
#8 49.81137 39.761656 55.89970 60.61688
2.2. 删除NA的问题
这种时候一般在一些数据缺失的情况下,而且缺失严重,比如调查问卷,很多后面的问题受试者没填就提交了,因此我们需要删除这些问题或受试者
2.2.1. 删除任何出现NA的行,很简单
##新建一个矩阵1:30(5*6),包含2个随机的NA
raw <- 1:30
raw[sample(raw,2)] <- NA
dim(raw) <- c(5,6)
raw <- data.frame(raw)
raw
# X1 X2 X3 X4 X5 X6
#1 1 NA 11 16 21 26
#2 2 7 12 17 22 27
#3 3 8 13 18 23 28
#4 4 NA 14 19 24 29
#5 5 10 15 20 25 30
na.omit(raw)
# X1 X2 X3 X4 X5 X6
#2 2 7 12 17 22 27
#3 3 8 13 18 23 28
#5 5 10 15 20 25 30
删除全列行NA其他方法可参考这篇帖子
2.2.2. 删除NA比例大的列
在分析数据的过程中,难免会有缺失值,有些变量缺失严重,而有些变量缺失值不多。这时我们便可以删除这些缺失值较多的变量,保留缺失值少的变量,后面可以用多重插补的方法填补缺失值,再进一步分析。
这里我们把raw表中NA比例大于
raw1 <- raw[,colSums(!is.na(raw))/nrow(raw) > 0.9]
raw1
# X1 X3 X4 X5 X6
#1 1 11 16 21 26
#2 2 12 17 22 27
#3 3 13 18 23 28
#4 4 14 19 24 29
#5 5 15 20 25 30
R语言中colSum、rowSums、colMeans、rowMeans、colMedians、rowMedians函数可以看这篇帖子