我有571列,对应于571种不同的代谢物,还有一列具有参与者ID。使用下面的代码,我可以单独识别每个代谢物具有异常值的参与者(平均值+/- 3* sd)。
out<-data
[which(
data$Met1 > mean(data$Met1, na.rm=T) + 3* sd(data$Met1, na.rm=T) |
data$Met1 > mean(data$Met1, na.rm=T) + 3* sd(data$Met1, na.rm=T)
),
]然而,我希望能够自动化这一点,所以输出是一个有572列的表,一列是ID编号,然后是571个代谢物的相应异常值,如果有的话,NAs填充了没有该ID异常值的代谢物的空白处。
ID Met1 Met2 Met3...
56 NA 0.145 NA
72 0.09 0.07 NA
98 NA NA 0.0098我正在处理for循环,但总是遇到错误。任何帮助都将不胜感激。
for ( i in 1:ncol(data[, 2:572]){
outlier1 <-data[,i] > mean(data[,i]) + 3*sd(data[, i])
outlier2 <- data[,i] > mean(data[,i]) - 3*sd(data[,i])
need <- outlier1 + outlier2
})发布于 2020-11-15 07:22:48
这里有一个很好的方法:构建一个自定义函数,然后将其应用于列:
## custom function
show_outliers = function(x) {
my_mean = mean(x)
my_sd = sd(x)
is_outlier = (x > my_mean + 3 * my_sd) | (x < my_mean - 3 * my_sd)
x[!is_outlier] = NA
return(x)
}
## intialize output
out = data
## apply function to all columns except the first
out[-1] = lapply(out[-1], show_outliers)如果你想修复你的for循环,我想这是可行的:
out <- data ## work on out, don't modify data
for (i in 2:ncol(out) { ## start at 2, go to ncol(out)
outlier1 <- out[,i] > mean(out[,i]) + 3*sd(out[, i])
outlier2 <- out[,i] > mean(out[,i]) - 3*sd(out[,i])
## your outlier1 and outlier2 are logical
## so we can combine them with OR |
outliers <- outlier1 | outlier2
## modify the data
out[!all_outliers, i] <- NA
} # delete extra )发布于 2020-11-15 07:46:31
我们可以使用boxplot.stats来查找异常值
library(dplyr)
data1 <- data %>%
mutate(across(-1,
~ replace(., . %in% boxplot.stats(.)$out, NA)))https://stackoverflow.com/questions/64839583
复制相似问题