2016-10-31 2 views
0

Ich habe eine for-Schleife innerhalb einer Funktion, und es läuft gut für Datenrahmen, die < 10000 Zeilen haben, aber die für die Schleife verwendete Zeit erhöht exponentiell mit der Anzahl der Zeilen erhöhen. Ich habe gelesen this Post über die Optimierung von Schleifen. Obwohl, ich weiß nicht, wie esWie wird dies für die Schleife in R optimiert?

Hier ist die unten Schleife auf meine Situation anzuwenden:

for (i in 1:nrow(data.frame)) { 
    event <- as.character(data.frame[i,"Event"]) 
    if(i < 20) { 
     # do nothing 
    } 
    else { 
     # Get the previous 20 rows 
     one.sec.interval = data[(i - (20 - 1)):i,] 
     #  print(head(one.sec.interval)) 

     # get the covariance matrix 
     cov.matrix <- var(one.sec.interval) 

     # get the variance of the features 
     variance.of.features <- diag(cov.matrix) 

     # reformat the variance vector into data frame for easier manipulation 
     variance.of.features <- matrix(variance.of.features,1,length(variance.of.features)) 
     variance.of.features <- data.frame(variance.of.features) 

     # rename the variance column of the features 
     colnames(variance.of.features) <- c('Back.Pelvis.Acc.X.sd', 'Back.Pelvis.Acc.Y.sd', 'Back.Pelvis.Acc.Z.sd', 
     'Back.Pelvis.Gyro.X.sd', 'Back.Pelvis.Gyro.Y.sd', 'Back.Pelvis.Gyro.Z.sd', 
     'Back.Trunk.Acc.X.sd', 'Back.Trunk.Acc.Y.sd', 'Back.Trunk.Acc.Z.sd', 
     'Back.Trunk.Gyro.X.sd', 'Back.Trunk.Gyro.Y.sd', 'Back.Trunk.Gyro.Z.sd') 

     # create the new feature vector 
     new.feature.vector <- cbind(data[i,], variance.of.features) 
     new.feature.vector$Event <- event 
     one.sec.interval.data[i- (20 - 1),] <- new.feature.vector 
    } 
} 
+2

Es wird nicht viel in Bezug auf die Leistung tun, aber für die Lesbarkeit können Sie beginnen, indem Sie die Iterationssequenz in '21: nrow (data.frame)' ändern. Dadurch können Sie die 'if'-Anweisung entfernen (da Ihre Schleife nichts tut, wenn' i <20 'ist). – seasmith

+1

Ich würde auch vorschlagen, Matrizen anstelle von Datenrahmen zu verwenden. Sie sind viel schneller, wenn Sie Teilmengenreihen verwenden. –

+0

Danke, ich werde versuchen, dass – YellowPillow

Antwort

0

wenn Sie Matrizen verwenden, die auch funktionieren könnte. Alternativ:

Schritt 1: unbedingt data.table Paket verwenden; es ist extrem schnell. Schritt 2: Setzen Sie das Ereignis als Zeichen vor der Schleife. Schritt 3: Wenn möglich, keine if-Schleifen haben. In diesem Fall stellen nur ich von 20 auf die vollständige Liste zu gehen, statt überprüfen, ob sie niedriger ist als 20:

library(data.table) 
data.table$Event <- as.character(data.table$event) 
for (i in 20:nrow(data.table)) { 
    ...do stuff... 
} 

Schritt 4: Sie können Setup die data.table Spalten vor der Zeit und benennen Sie sie Am Ende.

data.table <- data.table("Col Name 1"=character(),"Col Name 2"=numeric()...etc) 

Schritt 5: Dies ist möglicherweise nicht möglich, abhängig davon, wie Ihre Daten strukturiert sind. Sie können aber auch die Parallelverarbeitung mit dem DoMC-Paket und einer foreach-Schleife verwenden. Dies erfordert, dass jeder Lauf nicht von den Daten eines anderen Laufs abhängt. Nicht sicher, ob das für Sie gilt oder nicht.

--Hope das hilft!

+0

Nun können Sie stattdessen as.data.table() verwenden. Aber die Verwendung von data.table ist nicht unbedingt schneller. Insbesondere ermöglicht es Ihnen, sehr schnell eine Teilmenge zu bilden. Beispiel: setkey (df, "Name des Spaltennamens, den Sie unterteilen möchten") newset <- df [J ("Wert zu Teilmenge von"), Nomatch = 0L] – mjfred

+0

Wieder hängt es von Ihren Daten ab Sie können es parallelisieren: ein <- foreach – mjfred