2013-08-28 3 views
1

Я хотел бы, чтобы сформировать один data.frame из списков в спискеКак сгладить два списка в списке без использования data.table?

L1 <- list(A = c(1, 2, 3), B = c(5, 6, 7)) 
L2 <- list(A = c(11, 22, 33), B = c(15, 16, 17)) 
L3 <- list(L1, L2) 
L3 

library(data.table) 

Согласно «data.table» инструкции: «rbindlist" То же, что do.call (»rbind», л), но гораздо быстрее»

Я хотел бы добиться того, что„rbindlist“делает с помощью R базового пакета

rbindlist делает именно то, что мне нужно, но„“do.call не!

rbindlist(L3) 

do.call не делать то, что я хочу

do.call(rbind, L3) 

identical(rbindlist(L3), do.call(rbind, L3)) 

ответ

5

Я думаю, называя as.data.frame каждый время может быть дорогостоящим. Как насчет?

as.data.frame(do.call(mapply, c(L3, FUN=c, SIMPLIFY=FALSE))) 

mapply в основном занимает первые элементы L3 и применяет функцию FUN, а затем 2-го элемента и так далее ... Предположим, вы бы два списка (L3[[1]] и L3[[2]]), то вы могли бы сделать:

mapply(FUN=c, L3[[1]], L3[[2]], SIMPLIFY=FALSE) 

Здесь SIMPLIFY=FALSE гарантирует, что выходной сигнал не преобразуется (или упрощается) в матрицу. Таким образом, это будет список. Для общего случая мы используем do.call и передаем наш список со всеми остальными аргументами для функции mapply. Надеюсь это поможет.


Бенчмаркинг на большие данные:

ll <- unlist(replicate(1e3, L3, simplify=FALSE), rec=FALSE) 

aa <- function() as.data.frame(do.call(mapply, c(ll, FUN=c, SIMPLIFY=FALSE))) 
bb <- function() do.call(rbind, lapply(ll, as.data.frame)) 

require(microbenchmark) 
microbenchmark(o1 <- aa(), o2 <- bb(), times=10) 

Unit: milliseconds 
     expr  min   lq  median   uq  max neval 
o1 <- aa() 4.356838 4.931118 5.462995 7.623445 20.5797 10 
o2 <- bb() 673.773795 683.754535 701.557972 710.535860 724.2267 10 

identical(o1, o2) # [1] TRUE 
+1

+1. Конечно, если мы идем по скорости, а тусклость всех наших элементов списка одинакова, и мы уже знаем, что это такое: 'A <- unlist (ll, use.names = FALSE); dim (A) <- c (3, 2, 2000); примените (A, 2, I) '. Много «если», хотя :) – A5C1D2H2I1M1N2O1R2T1

+1

Спасибо, Арун, ваше решение идеально. Однако я не понимаю args = c (applyMeanList, FUN = c, SIMPLIFY = FALSE)) для do.call. можете ли вы предоставить дополнительные разъяснения. –

3

Вы должны преобразовать подсписки в L3 к data.frame с первым:

> do.call(rbind, lapply(L3, as.data.frame)) 
    A B 
1 1 5 
2 2 6 
3 3 7 
4 11 15 
5 22 16 
6 33 17 
Смежные вопросы