R foreach с .combine = rbindlist

Я использую foreach с .combine = rbindlist. Это не работает, хотя он отлично работает, если я использую .combine = rbind.

Просто для иллюстрации с использованием простого примера -

> t2 <- data.table(col1=c(1,2,3))
> foreach (i=1:3, .combine=rbind) %dopar% unique(t2)
   col1
1:    1
2:    2
3:    3
4:    1
5:    2
6:    3
7:    1
8:    2
9:    3

# But using rbindlist gives an error

> foreach (i=1:3, .combine=rbindlist) %dopar% unique(t2)
error calling combine function:
<simpleError in fun(result.1, result.2): unused argument(s) (result.2)>
NULL

Кто-нибудь мог сделать эту работу?

Спасибо заранее.

Ответы

Ответ 1

В основном, что вы сказали - rbindlist принимает аргумент list, а ошибка, которую вы получаете, такая же, как и эта:

result.1 = data.table(blah = 23)
result.2 = data.table(blah = 34)

rbindlist(result.1, result.2)
#Error in rbindlist(result.1, result.2) : unused argument (result.2)

Если вы хотите использовать rbindlist, способ сделать это будет следующим:

rbindlist(foreach (i = 1:3) %dopar% unique(t2))

или это:

foreach (i=1:3, .combine=function(x,y)rbindlist(list(x,y))) %dopar% unique(t2)

Ответ 2

Здесь можно использовать rbindlist как функцию .combine и иметь .multicombine=TRUE:

foreach (i=1:3,
         .combine=function(...) rbindlist(list(...)),
         .multicombine=TRUE) %dopar% unique(t2)

Если у вас есть приличное количество отдельных результатов для агрегирования, это может быть довольно немного быстрее, чем объединение двух-в то время.

Для одного оператора foreach это дает тот же результат, что позволяет foreach default .combine перечислить и обернуть с помощью rbindlist, как в первом решении eddi. Я не уверен, что быстрее, хотя я ожидаю, что они будут близки.

Для небольших одиночных заданий foreach мне нравится обертывание с помощью rbindlist, но при соединении нескольких foreach вместе с %:% я думаю, что вышеупомянутый подход (вероятно, в первом foreach) выглядит более чистым.