首页 > 解决方案 > `lapply` 是否可以在“超时”约束下返回部分处理结果?

问题描述

我有一些代码需要很长时间才能执行。因此,我使用R.util's withTimeout。合成器是这样的:

res <- withTimeout({
  v1 %>% mutate(Output = unlist(lapply(as.list(data.frame(t(v1))),function(x) 
  SomeFunction(x))))
}, timeout = 2, onTimeout = "warning")

在我的代码中,v1是一个包含许多行的数据框,并且该函数按行工作(使用lapply)。我允许该功能运行 2 秒,如果需要更长时间,它会输出警告。但是,已经完成的输出似乎没有保存在任何地方!如何更改代码以便返回输出本身以及警告?

标签: rtimeoutlapply

解决方案


出于好奇,我尝试了以下方法,似乎效果很好。

## an example data frame of 1000 columns
## `lapply` will loop a function over it column by column
x <- data.frame(matrix(sample.int(2, 2 * 1000, TRUE), 2, 1000))

## actually a wrapper function of your `SomeFunction`
## it takes an additional `time_limit` (in seconds)
## is also access a GLOBAL variable `elapsed_time`
f <- function (x, time_limit) {
  if (elapsed_time < time_limit) {
    t1 <- proc.time()[[3]]
    z <- tabulate(sample(x, 1e+5, TRUE))  ## an arbitrary example function here
    t2 <- proc.time()[[3]]
    elapsed_time <<- elapsed_time + (t2 - t1)  ## note the `<<-`
    } else {
    z <- NULL
    }
  z
  }

elapsed_time <- 0                  ## elapsed time counter (in global environment)
oo <- lapply(x, f, time_limit = 2) ## 2 seconds time limit

elapsed_time
#[1] 2.002

sum(sapply(oo, is.null))
#[1] 693

所以在我的笔记本电脑上,迭代在 (1000 - 693) = 307 轮之后终止。lapply仍然返回一个长度为 1000 的列表,但只有前 307 个元素保存处理结果,而其余 693 个条目是NULL.

实际上,这是一个很好的例子,在哪里<<-会有用。


推荐阅读