首页 > 解决方案 > 如何使我的函数更快地检查哪些值未按升序排序?

问题描述

我写了一个函数来检查向量中的哪些值没有按升序排列。因此,检查向量中的每个元素是否高于其左侧的所有元素。

然后我将此功能用于分组数据,但需要很长时间(大约 6-7 分钟)。我的原始数据有近 300 万行和 13,480 个组。

我的代码:

  check_which_not_ordered <- function(x) {  

      res <- rep(NA, length(x))

      for(i in 1:length(x)) {
         for (j in 1:i) {
         res[i] <- all(x[i] >= x[1:j])
         }
      }

  return(res) 

  }

  setDT(dt)[, ordered := check_which_not_ordered(no_of_reviews), 
            by = .(country, id)] 

小数据样本:

  dtt <- data.frame(country = c(rep("USA", 10), rep("Canada", 10)),
             id = c(rep(1, 5), rep(2, 5), rep(3, 5), rep(4, 5)),
             no_of_reviews = c(c(10, 12, 3, 4, 13), 
                             c(2, 3, 4, 5, 6),
                             c(7, 9, NA, 7, NA),
                             c(NA, 7, 2, 9, 10)))

输出检查哪些元素未正确按升序排序为 FALSE。我想知道我是否可以更快地达到相同的结果?

标签: rfor-loopdata.table

解决方案


使用该cummax()函数,查看每个元素是否等于同一位置的累积最大值。然后把NA放回去。

library(microbenchmark)
dtt <- data.frame(country = c(rep("USA", 10), rep("Canada", 10)),
                  id = c(rep(1, 5), rep(2, 5), rep(3, 5), rep(4, 5)),
                  no_of_reviews = c(c(10, 12, 3, 4, 13), 
                                    c(2, 3, 4, 5, 6),
                                    c(7, 9, NA, 7, NA),
                                    c(NA, 7, 2, 9, 10)))


check_which_not_ordered <- function(x) {  

  res <- rep(NA, length(x))

  for(i in 1:length(x)) {
    for (j in 1:i) {
      res[i] <- all(x[i] >= x[1:j])
    }
  }

  return(res) 

}

check_which_not_ordered2 <- function(x) {
  na_inds <- which(is.na(x))
  x[na_inds] <- min(x) - 1
  res <- x == cummax(x)
  res[na_inds] <- NA
  return(res)
}


x = dtt$no_of_reviews

microbenchmark(check_which_not_ordered(x), check_which_not_ordered2(x))
#> Unit: nanoseconds
#>                         expr   min       lq      mean   median       uq
#>   check_which_not_ordered(x) 97185 128197.5 167051.89 133333.5 135901.5
#>  check_which_not_ordered2(x)   790   1185.0  24845.53   1580.0   1975.0
#>      max neval
#>  3863309   100
#>  2304395   100

reprex 包(v0.3.0)于 2019 年 9 月 19 日创建


推荐阅读