【问题标题】:How to avoid looping over rows and columns to increase speed in R如何避免循环遍历行和列以提高 R 的速度
【发布时间】:2021-12-02 15:57:22
【问题描述】:

我是新的 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 * 分位数间距;

转换为中位数。

【问题讨论】:

  • 你能写出异常值的规则以及如何处理它们吗?至于你的问题:它认为有可能利用矢量化函数(即一次处理一列而不是一次处理一个“单元格”。)
  • 规则:高于 75% 分位数的数据点 + 1.5 * 四分位间距;低于 75% 分位数的数据点 - 1.5 * 分位数间距;转换为中位数。
  • 您的意思是“低于 25% 的数据点”分位数吗?
  • 是的。正是我的意思。
  • 下面的答案是否提高了执行速度?

标签: r loops vectorization apply


【解决方案1】:

1.我们创建一个规则函数,在其中我们使用矢量化的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.然后我们将函数应用到矩阵的每一列:

apply(data_X, 2, rule_function)

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

【讨论】:

    猜你喜欢
    • 2017-07-04
    • 2019-08-11
    • 2021-11-07
    • 2021-08-20
    • 1970-01-01
    • 2018-03-13
    • 2016-06-28
    • 1970-01-01
    • 2015-05-31
    相关资源
    最近更新 更多