2015-11-26 2 views
0

У меня иногда есть длинные * петли ply в R, где, например, API вызывается на каждой итерации.Сохранить вывод из прерванного цикла/* ply

Мне интересно, можно ли вручную прервать функцию * ply после ее запуска, в то время как возвращение последней завершенной итерации сохраняется.

Когда я использую цикл for и заранее создаю пустой объект, где я присоединяю возврат цикла на каждой итерации к одному и тому же объекту, у меня есть такой частичный возврат в случае ручного прерывания. Мне интересно, возможно ли это для семейства функций.

Я знаю, что лучший способ сделать это - сначала проверить цикл с небольшим количеством итераций, а затем запустить его в комплекте. Другим способом было бы использовать tryCatch() или цикл foreach() с .errorhandling="pass", чтобы избежать прерванного цикла из-за плохих возвратов. Тем не менее, я ищу способ ручного прерывания.

Прямо сейчас я использую функцию save() для записи на диск, но это значительно замедляет работу и поэтому не представляется возможным. Я бы предположил, что можно записать в ранее создаваемую среду на assign(), но это также немного хакерское и может привести к неправильной перезаписке.

Оптимальным было бы, если кто-то знает способ сделать это с помощью dplyr's do().

+2

Я не думаю, что это возможно, поскольку функции не работают таким образом, чтобы обеспечить частичный выход, но было бы интересно доказать, что это неправильно. –

ответ

1

Я предполагаю, что на * ply вы имеете в виду семейство apply (нанесите, sapply, 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 - ответ здесь.

+0

3 года R и я никогда не знал о '<< -' ... большое спасибо, он отлично работает. Чтобы уточнить, я также имел в виду функции «ply» из функций plyr или отображения, например 'do' из dplyr. И ваш подход там работает! Я добавлю пример вашего ответа. – zerweck

Смежные вопросы