2012-11-05 4 views
44

У меня есть список длиной 130 000, где каждый элемент является символьным вектором длины 110. Я хотел бы преобразовать этот список в матрицу размером 1,430,000 * 10. Как я могу сделать это более эффективно? Мой код:Как преобразовать список в матрицу более эффективно в R?

output=NULL 
for(i in 1:length(z)) output=rbind(output,matrix(z[[i]],ncol=10,byrow=T)) 
+2

Если вы хотите, размеры быть 1430000 * 11 почему вы устанавливаете ncol как 10? – Dason

+1

Подождите, когда вы говорите, что каждая запись имеет 11 символов, вы имеете в виду, что это вектор с 11 элементами? Первоначально я думал, что каждая из них содержит строку с 11 символами. Вы можете показать 'z [1: 2]' в качестве примера? –

+0

Спасибо Дасону и Дэвиду! Это опечатка. Я исправил это. – user1787675

ответ

99

Это должно быть эквивалентно текущему коду, только намного быстрее:

output <- matrix(unlist(z), ncol = 10, byrow = TRUE) 
+4

Бинго. Это должно быть намного быстрее, чем мое решение, но я не мог думать об этом достаточно быстро. –

+9

+1, но я бы рекомендовал установить 'USE.NAMES = FALSE' в' unlist', чтобы сэкономить время и память. –

+1

Это должно быть 'use.names' (т. Е. В нижнем регистре). –

5

Это помогло бы иметь образец информации о вашей продукции. Рекурсивно с использованием rbind на больших и больших вещах не рекомендуется. Моя первая догадка на что-то, что помогло бы вам:

z <- list(1:3,4:6,7:9) 
do.call(rbind,z) 

См a related question для большей эффективности, если это необходимо.

11

Я думаю вы хотите

output <- do.call(rbind,lapply(z,matrix,ncol=10,byrow=TRUE)) 

т.е. объединение @ использование BlueMagister о do.call(rbind,...) с lapply заявления, чтобы преобразовать отдельные элементы списка в 11 * 10 матриц ...

контрольных показателей (показывая @ Решение flockel unlist в 5 раз быстрее, чем мое, и в 230 раз быстрее, чем исходный подход ...)

n <- 1000 
z <- replicate(n,matrix(1:110,ncol=10,byrow=TRUE),simplify=FALSE) 
library(rbenchmark) 
origfn <- function(z) { 
    output <- NULL 
    for(i in 1:length(z)) 
     output<- rbind(output,matrix(z[[i]],ncol=10,byrow=TRUE)) 
} 
rbindfn <- function(z) do.call(rbind,lapply(z,matrix,ncol=10,byrow=TRUE)) 
unlistfn <- function(z) matrix(unlist(z), ncol = 10, byrow = TRUE) 

##   test replications elapsed relative user.self sys.self 
## 1 origfn(z)   100 36.467 230.804 34.834 1.540 
## 2 rbindfn(z)   100 0.713 4.513  0.708 0.012 
## 3 unlistfn(z)   100 0.158 1.000  0.144 0.008 

Если этот весы соответствующим образом (т.е. вы не сталкиваетесь с проблемами памяти), полная проблема займет около 130 * 0,2 секунды = 26 секунд на сопоставимой машине (я сделал это на двухлетнем MacBook Pro).

+0

Это волшебство! Это занимает около 20 секунд, чтобы сделать это на моей однолетней машине toshiba, что экономит мне много времени. И очень интересна ваша функция, чтобы показать время выполнения. – user1787675

-2

вы можете использовать as.matrix, как показано ниже:

output <- as.matrix(z) 
Смежные вопросы