替代嵌套for do循环

问题描述 投票:-1回答:1

我有一个名为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条件将相应地执行)。然而,我的目标是在减少运行时间方面获得一种可能的替代方案,因此我尽可能地简化原始代码以达到主要目的

r dataframe replace nested-loops
1个回答
1
投票

你不想为此使用循环。你可以试试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
© www.soinside.com 2019 - 2024. All rights reserved.