r - 如何使我的函数更快地检查哪些值未按升序排序?
问题描述
我写了一个函数来检查向量中的哪些值没有按升序排列。因此,检查向量中的每个元素是否高于其左侧的所有元素。
然后我将此功能用于分组数据,但需要很长时间(大约 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。我想知道我是否可以更快地达到相同的结果?
解决方案
使用该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 日创建
推荐阅读
- c# - 在 Blazor 中将文本转换为始终为大写
- javascript - 如何将从打字稿转译的节点模块导入 Nuxt?
- verilog - 当我执行合成时收到警告第 49 行:9 位表达式的结果被截断以适合 8 位目标?
- c - C libcurl 程序在 Eclipse 上立即终止
- c++ - C++ 赋值运算符在类的易失性和非易失性实例之间进行复制
- jq - 根据对子元素数组的搜索选择元素,为数组中的每个匹配项返回一次元素
- angular - 角度测试床模拟服务
- python - Python tkinter 下拉菜单
- python-3.x - 如何在某个日期范围内获取熊猫数据框中的数据
- php - 如何使用 Laravel 将两个表与数据透视表连接起来?