如何避免循环遍历行和列以提高 R 中的速度

How to avoid looping over rows and columns to increase speed in R

我是 R 的新用户,第一份工作需要使用该软件。我试着在网站上寻找与我类似的问题,但没有找到。抱歉,如果我的问题是多余的。

我遇到的问题是我需要编辑每一列中的离群值。下面是一个可重现的例子:

    data_X <- matrix(data = rep(1,100), nrow = 10, ncol = 10)

for (i in 1:nrow(data_x)) {
  for (j in 1:ncol(data_x)) {
    if (is.na(data_x[i,j])) {
      data_x[i,j] <- NA
    } else if (data_x[i,j]>(quantile(data_x[[j]], 0.75, na.rm=T)+1.5*(quantile(data_x[[j]], 0.75,na.rm=T)-quantile(data_x[[j]], 0.25,na.rm=T)))) {
      data_x[i,j]=(quantile(data_x[[j]], 0.5, na.rm=T))
    } else if (data_x[i,j]<(quantile(data_x[[j]], 0.25, na.rm=T)-1.5*(quantile(data_x[[j]], 0.75, na.rm=T)-quantile(data_x[[j]], 0.25, na.rm=T)))) {
      data_x[i,j]=(quantile(data_x[[j]], 0.5, na.rm=T))
    } else {
      data_x[i,j]=data_x[i,j]
    }
  }
}

实际上,矩阵的维度要大得多,循环遍历代码大约需要4分钟。这对我来说太长了,我想知道是否有更优雅的方式。

我做了一些研究,显然 apply() 不会提高速度...

编辑:

规则:

高于 75% 分位数的数据点 + 1.5 * 四分位数分布;

低于 25% 分位数的数据点 - 1.5 * 分位数分布;

均转换为中位数。

1.We 创建一个规则函数,我们在其中使用向量化 ifelse.

rule_function <- function(x) {
  
  q25 <- quantile(x, 0.25, na.rm = TRUE)
  q75 <- quantile(x, 0.75, na.rm = TRUE)
  iqr <- q75 - q25
  lower <- q25 - 1.5 * iqr
  upper <- q75 + 1.5 * iqr
  
  result <- ifelse(x < lower | x > upper, median(x, na.rm = TRUE), x)

  return(result)  
}

2.And 然后我们将函数应用于矩阵的每一列:

apply(data_X, 2, rule_function)

示例数据实际上不允许测试,所以我不能 100% 确定这是否对您有帮助。但是,对于 10000 x 10000 矩阵,这只需要几秒钟(是否 取决于您的实际用例;)