保存中断循环/ * ply

时间:2015-11-26 08:26:53

标签: r dplyr

我有时在R中有冗长的* ply循环,例如在每次迭代中调用API。

我想知道在启动后是否可以手动中断* ply函数,而最后完成的迭代的返回仍然保存。

当我使用for循环并预先构造一个空对象时,我在每次迭代中将循环的返回附加到同一个对象,在手动中断的情况下我有这样的部分返回。我想知道这对* ply系列函数是否可行。

我知道更好的方法是先用少量迭代检查循环,然后让它在整个集合中运行。另一种方法是使用tryCatch()foreach()循环与.errorhandling="pass"来避免错误返回的中断循环。不过,我正在寻找手动中断的方法。

现在我使用save()函数写入磁盘,但这会大大减慢速度,因此不可行。我认为可以通过assign()写入以前创建的环境,但这也有点hackish并且可能导致错误的覆盖。

如果有人知道使用dplyr do()执行此操作的方法,最好的事情就是。

1 个答案:

答案 0 :(得分:1)

我认为,* ply你的意思是apply家族(申请,申请,lapply,tapply等)。如果没有,我很抱歉。

尽管如此,我认为您可以使用<<-运算符轻松实现所需目标。但这会影响你的表现。

# Let's assume that your loop output is computed by this function :
> do.some.stuff <- function(p) {
+     p
+ }
# If we want to save the last output…
> ret <- sapply(1:100000,function(x) {
+     to.save <<- do.some.stuff(x)
+     to.save
+ })
> to.save
[1] 100000
# If we want to save all the computed outputs…
> to.save <- vector()
> ret <- sapply(1:100000,function(x) {
+     ret <- do.some.stuff(x)
+      to.save <<- c(to.save, ret)
+      ret
+ })
^C  # <-- manual interruption
> str(to.save)
 int [1:21753] 1 2 3 4 5 6 7 8 9 10 ...


# Example for dplyr and do():
library(dplyr)
system.time({
      to.save <- vector()
      final.ret <- sample_n(iris,10e4,replace=T) %>% rowwise %>% do(w_mean={
        ret <- round(.$Sepal.Width,digits=1)
        to.save <<- c(placeholder,out)
        ret
      })
})
# Commenting out the assignment saves about 80 seconds for me.

但是,对性能的影响非常重要。此外,它不是使用apply函数的自然方式。也许for就是答案。