我有一个名为df的数据框,200多个变量,300,000多个观测值(200多列,300000多行)
我的R代码的最终目标是找到每列的异常值,并用一定的值替换它们,比如NA。如果该值已经是NA,则跳过并继续下一个循环
for (j in 1:ncol(df)){
outnumtext <- paste0('out_value <- boxplot.stats(df$',colnames(df[j]),')$out')
eval(parse(text=outnumtext))
for (k in 1:nrow(df)){
replacetext <- paste0('
if ((df[',k,',',j,'] %in% out_value) & !(is.na(df[',k,',',j,']))) {
df[',k,',',j,'] <- NA
} else if (is.na(df[',k,',',j,'])) {
next
} else {
next
}')
eval(parse(text=replacetext))
}
}
我发现在r中使用for循环并循环遍历每列中的每一行,大大减慢了运行速度。有没有其他选择?
非常感谢你提前!
编辑P / S:真正的代码不只是用NA替换异常值,而且还有几种基于几种条件的处理方式(if if if if条件将相应地执行)。然而,我的目标是在减少运行时间方面获得一种可能的替代方案,因此我尽可能地简化原始代码以达到主要目的
你不想为此使用循环。你可以试试dplyr::mutate_all()
。
它仍然会超过300K +行,但应该比循环更好。
library(dplyr)
df <- df %>%
mutate_all(funs(ifelse(. %in% boxplot.stats(.)$out, NA, .)))
例:
exdata <- structure(list(x = c(200, 6, 8, 2, 7, 1, 4, 9, 3, 5, 1000),
y = c(300, 1, 18, 3, 2, 16, 14, 9, 11, 6, 100)),
row.names = c(NA, -11L),
class = "data.frame")
exdata
x y
1 200 300
2 6 1
3 8 18
4 2 3
5 7 2
6 1 16
7 4 14
8 9 9
9 3 11
10 5 6
11 1000 100
data1 %>%
mutate_all(funs(ifelse(. %in% boxplot.stats(.)$out, NA, .)))
x y
1 NA NA
2 6 1
3 8 18
4 2 3
5 7 2
6 1 16
7 4 14
8 9 9
9 3 11
10 5 6
11 NA NA