Подтвердить что ты не робот

R: преобразование каждой строки кадра данных в элемент списка

У меня есть ряд операций с кадрами данных, которые я хотел бы ускорить с помощью mclapply() или других lapply() подобных функций. Один из самых простых способов борьбы с этим - сделать каждую строку кадра данных небольшим фреймом данных в списке. Я могу сделать это довольно легко с помощью plyr следующим образом:

df <- data.frame( a=rnorm(1e4), b=rnorm(1e4))
require(plyr)
system.time(myList <- alply( df, 1, function(x) data.frame(x) ))

Как только у меня есть данные в виде списка, я могу легко делать такие вещи, как:

mclapply( myList, function(x) doSomething(x$a) )

Это работает плавно, но у меня довольно много данных, а шаг adply() довольно медленный. Я попытался использовать многоядерный параллельный бэкэнд на шаге adply, но он никогда не использовал больше одного процессора, хотя я зарегистрировал 8. Я подозрительно, что параллельная опция может не работать с этим типом проблемы.

Любые советы о том, как сделать это быстрее? Может быть, базовое решение R?

4b9b3361

Ответ 1

Просто используйте split. Это в несколько раз быстрее, чем ваша строка adply.

> system.time(myList <- alply( df, 1, function(x) data.frame(x) ))
   user  system elapsed 
   7.53    0.00    7.57 
> system.time( splitList <- split(df, 1:NROW(df)) )
   user  system elapsed 
   1.73    0.00    1.74 
> 

Я подозреваю, что параллельный бэкэнд на adply предназначен только для оценки функции (не расщепления и повторного объединения).

UPDATE:
Если вы можете преобразовать ваш data.frame в матрицу, решение ниже будет быстрым. Вы можете использовать split, но он будет отбрасывать имена и возвращать вектор в каждом элементе списка.

> m <- as.matrix(df)
> system.time( matrixList <- lapply(1:NROW(m), function(i) m[i,,drop=FALSE]) )
   user  system elapsed 
   0.02    0.00    0.02
> str(matrixList[[1]])
 num [1, 1:2] -0.0956 -1.5887
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "a" "b"
> system.time( matrixSplitList <- split(m, 1:NROW(m)) )
   user  system elapsed 
   0.01    0.00    0.02 
> str(matrixSplitList[[1]])
 num [1:2] -0.0956 -1.5887

Ответ 2

Как насчет этого?

jdList <- split(df, 1:nrow(df))

> class(jdList[[1]])
[1] "data.frame"

> system.time(jdList <- split(df, 1:nrow(df)))
   user  system elapsed 
   1.67    0.02    1.70 
> system.time(myList <- alply( df, 1, function(x) data.frame(x) ))
   user  system elapsed 
    7.2     0.0     7.3