webentwicklung-frage-antwort-db.com.de

Wie kann man eine große Liste von Vektoren in R effizienter in eine Matrix konvertieren?

Ich habe eine Liste der Länge 130.000, wobei jedes Element ein Zeichenvektor der Länge 110 ist. Ich möchte diese Liste in eine Matrix der Dimension 1.430.000 * 10 konvertieren. Wie kann ich das effizienter machen? Mein Code lautet:

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

Dies sollte Ihrem aktuellen Code entsprechen, nur viel schneller:

output <- matrix(unlist(z), ncol = 10, byrow = TRUE)
118
flodel

Ich denke du willst

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

die Kombination von @ BlueMagisters Verwendung von do.call(rbind,...) mit einer lapply-Anweisung, um die einzelnen Listenelemente in 11 * 10-Matrizen umzuwandeln ...

Benchmarks (die @ flodel-Lösung unlist ist 5x schneller als meine und 230x schneller als der ursprüngliche Ansatz ...)

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 

Wenn dies angemessen skaliert wird (d. H., Dass Sie keine Speicherprobleme haben), würde das gesamte Problem auf einem vergleichbaren Computer etwa 130 * 0,2 Sekunden = 26 Sekunden dauern (ich habe dies auf einem zwei Jahre alten MacBook Pro getan).

15
Ben Bolker

Es wäre hilfreich, Beispielinformationen zu Ihrer Ausgabe zu haben. Die Verwendung von rbind bei größeren und größeren Dingen ist nicht empfohlen. Meine erste Vermutung zu etwas, das Ihnen helfen würde:

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

Siehe eine verwandte Frage für mehr Effizienz, falls erforderlich.

5
Blue Magister

Sie können auch verwenden,

output <- as.matrix(as.data.frame(z))

Die Speicherbelegung ist sehr ähnlich

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

Was kann mit mem_changed() von library(pryr) verifiziert werden.

0
csta