我有一个数据框,名称为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 else条件将相应执行的话)的几种处理方式。但是我的目标是找到减少运行时间的可能选择,因此我尝试了尽可能简化我的原始代码以达到关键点
答案 0 :(得分:1)
您不想为此使用循环。您可以尝试dplyr::mutate_all()
。
在超过30万行时,它仍然会很慢,但应该比循环更好。
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