2016-07-12 15 views
1

Ich habe Schwierigkeiten, eine Matrix innerhalb einer Lapply-Schleife zu füllen.Lapply Zeilen an Matrix anfügen

In meinen Daten habe ich eine Liste von 135 Geospatial-Punkten. Innerhalb der Lappy-Schleife berechne ich verschiedene Metriken basierend auf der Landschaft innerhalb von 3 verschiedenen Radien von diesen Standortkoordinaten. Was ich tun möchte, ist zyklisch durch jede Kombination von 135 Seiten und 3 Radien, dann füllen Sie jede Zeile meiner leeren, vorbereiteten Matrix mit der (Website, Radius, Metrik1, Metrik2, Metrik3).

Ich habe ein einfaches Skript erstellt, das das Problem reproduziert, in das ich hineinlaufe. Wenn es möglich ist, für mich, den do.call(rbind, absdf) Befehl anzuwenden, wie in here dann habe ich noch nicht herausgefunden, wie ...

# Generate empty matrix: 
mymatrix <- matrix(,nrow=18, ncol=5) 

# A vector with length of x (in my data this is the list of 135 sites): 
a <- 1:6 
#These sets will represent my metrics 
b <- rnorm(6, 5, 10) 
c <- rnorm(6, 100, 20) 
d <- rnorm(6, 20, 20) 

# Radius vector: 
rad <- c(100,200,300) 

# The loop: lapply for site within lapply for radius 
lapply(1:3,function(r){ 
    lapply(1:6,function(x){ 
    row.number <- (r-1)*6+x 
    tmpvector <- c(a[x], b[x], c[x], d[x], rad[r]) 
    mymatrix[row.number,] <- tmpvector 
    }) 
}) 
View(mymatrix) 

Mit dem Code wie jetzt geschrieben, die resultierende Matrix noch leer ist.

Wenn ich dieses einfache Beispiel als Schreib für Schleife

mymatrix <- matrix(,nrow=18, ncol=5) 

a <- 1:6 
b <- rnorm(6, 5, 10) 
c <- rnorm(6, 100, 20) 
d <- rnorm(6, 20, 20) 

rad <- c(100,200,300) 

for (r in 1:3) { 
    for (x in 1:6) { 
    row.number <- (r-1)*6+x 
    tmpvector <- c(a[x], b[x], c[x], d[x], rad[r]) 
    mymatrix[row.number,] <- tmpvector 
    } 
} 
View(mymatrix) 

dann füllt die Matrix mit Werten wie ich erwarte. Ich entschuldige mich, wenn ich einen einfachen Fehler mache: Ich bin sehr neu in diesen Loops!

NB Ich wäre auch offen für die Erstellung einer fortlaufenden Liste dieser Daten, die ich dann in ein nützlicheres Format umwandeln könnte!

Antwort

0

Wenn Sie es wirklich mit lapply tun wollen, hier eine ziemlich hässliche Art und Weise, es zu tun (und Sie fast da selbst waren):

set.seed(123) 
#we don't really need to initialise the matrix anymore 
#mymatrix <- matrix(,nrow=18, ncol=5) 

a <- 1:6 
b <- rnorm(6, 5, 10) 
c <- rnorm(6, 100, 20) 
d <- rnorm(6, 20, 20) 
rad <- c(100,200,300) 

#Generate the list of rows: 
rowList<-lapply(1:3,function(r){ 
        lapply(1:6,function(x){ 
           #data processing 
           #row.number <- (r-1)*6+x #actually this line is unnecessary 
           tmpvector <- c(a[x], b[x], c[x], d[x], rad[r]) 
        }) 
}) 

#creation of mymatrix -- method 1 
mymatrix<-as.matrix(data.frame(rowList)) 
colnames(mymatrix)<-NULL #since you probably don't want the ugly output 
mymatrix<-t(mymatrix) 

### OR 
#creation of my matrix -- method2 (with do.call and rbind) 
do.call(rbind,sapply(rowList,matrix)) 

Das Problem mit dem ersten Ansatz (dh versuchen Sie, die Matrix innerhalb der lapply zu ändern) ist, dass am Ende jeder Iteration Sie das letzte Ergebnis, das Sie erstellt haben, zurückgeben: die Erstellung der aktuellen Zeile und da kein Fehler, Nachricht oder Warnung erstellt wurde, haben Sie keine Ausgabe.

mymatrix bleibt so wie es war vor der Lapply-Schleife, da die gesamte Verarbeitung innerhalb { und } erfolgte und auch nicht gespeichert wurde.

BTW, wenn Sie alles mit der Ausgabe von lapply tun wollen, sollten Sie sie in einem Objekt speichern (oder direkt in eine andere Funktion, die ich nicht empfehlen werde, wenn Sie nicht mit der internen Logik vertraut sind von schlaflos).

Hoffentlich ist meine Erklärung nicht zu verworren und ein bisschen off-topic, aber ein guter Ort, um mit dem beginnen * an Familie und gleichwertig: R Grouping functions: sapply vs. lapply vs. apply. vs. tapply vs. by vs. aggregate

1

Mit lapply ist in dieser Situation nicht sehr natürlich. Sie benötigen für die Erstellung einer solchen Matrix keine Schleife, sondern können die Recycling-Eigenschaften von R verwenden.

mymatrix <- cbind(a, b, c, d, rep(c(100,200,300), each = 6)) 
+0

Es ist wahr, dass lapply nicht notwendig sind, um die Matrix zu erstellen in meinem Beispiel. Lapply ist jedoch für die iterativen geospatialen Verarbeitungsaufgaben in meinem vollständigen Skript erforderlich, die die Ausgabe erzeugen, die ich in einen Datenrahmen oder eine Matrix organisieren muss. Um ehrlich zu sein, wäre das Erstellen einer Liste auch für mich ausreichend, da ich diese Liste dann in ein nützlicheres Format umwandeln könnte. Danke für deinen Vorschlag, @Edwin! – Nematode