Применить rbindlist к функции, которая возвращает несколько таблиц

#r #data.table #lapply

#r #data.table #lapply

Вопрос:

Мы используем inner <- rbindlist(lapply(..., FUN)) для объединения результатов результатов моделирования, созданных с использованием future пакета. В данном конкретном случае rbindlist(lapply(..., FUN)) вложен, rbindlist(future_lapply(..., inner)) потому что моделирование распределено по потокам.

Это работает нормально, пока FUN() возвращает одну таблицу. Теперь мы хотим провести более подробный анализ моделирования, которое требует от нас возврата более одной таблицы FUN() . Теперь таблицы будут иметь разные формы, и мы хотим объединить похожие на похожие.

Как объединить таблицы вместе с помощью *apply() функции, если FUN() возвращает несколько таблиц? Мы придумали решение, которое работает ниже, но не так хорошо составляется. Любые предложения о том, как улучшить этот код, чтобы снова вписаться в *apply(X, FUN) структуру?

 foo <- list(
  list(data.table(a = 1), data.table(b = 2)), 
  list(data.table(a = 3), data.table(b = 4)),
  list(data.table(a = 5), data.table(b = 6))
)
MapRbind <- function(...) {
  Map(rbind, ...) 
}
do.call(MapRbind, foo)
  

Я не вижу способа переместить вызов в do.call() into MapRbind() .

Ответ №1:

Это все?

 MapRbind <- function(our_list) {
  do.call(function(...) Map(rbind, ...), our_list)
}

> MapRbind(foo)
[[1]]
   a
1: 1
2: 3
3: 5

[[2]]
   b
1: 2
2: 4
3: 6
  

Комментарии:

1. Спасибо, похоже, это действительно работает. Я вижу, что допустил ошибку при написании этой идеи.

2. Довольно элегантное решение, которое вы придумали — я просто переместил части. Я бы, вероятно, сделал что-то более простое, например: lapply(1:2, function(i) rbindlist(lapply(foo, "[[", i)))

3. Количество таблиц может варьироваться, и вызывающий может не знать об этом (может быть осведомлен, но я ленив), поэтому я предпочитаю это общее решение. Было бы еще лучше, если бы кто-нибудь знал способ сделать это без помощников и / или использования rbindlist

4. У меня была идея написать lapply(data.table::transpose(lapply(...)), rbindlist) , но transpose так не работает.

5. Вы могли бы сделать это с purrr : lapply(purrr::transpose(foo), rbindlist)