2012-10-11 583 views
17

Ich habe einen Datenrahmen von 150.000 Zeilen mit 2.000 Spalten mit Werten, einige davon sind negative. Ich ersetze diese negativen Werte durch 0, aber es ist extrem langsam (~ 60min oder mehr).Schnelles Ersetzen von Werten im Dataframe in R

df[df < 0] = 0

wo df[,1441:1453] sieht aus wie (alle Spalten/Werte numerisch):

V1441 V1442 V1443 V1444 V1445 V1446 V1447 V1448 V1449 V1450 V1451 V1452 V1453 
1  3  1  0  4  4 -2  0  3 12  5 17 34 27 
2  0  1  0  7  0  0  0  1  0  0  0  0  0 
3  0  2  0  1  2  3  6  1  2  1 -6  3  1 
4  1  2  3  6  1  2  1 -6  3  1 -4  1  0 
5  1  2  1 -6  3  1 -4  1  0  0  1  0  0 
6  1  0  0  1  0  0  0  0  0  0  1  2  2 

Gibt es eine Möglichkeit, solche Verfahren zu beschleunigen, zum Beispiel so, wie ich es tue, ist äußerst langsam, und es gibt einen schnelleren Ansatz dafür? Danke.

+0

150.000 Zeilen x 2000 Spalten ersetzt: dies richtig ist –

+0

Können Sie bitte [uns zeigen] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) wie Ihre Daten aussehen? Sind alle Spalten numerisch? – Roland

Antwort

29

Versuchen Sie, Ihre df zu einer Matrix zu transformieren.

df <- data.frame(a=rnorm(1000),b=rnorm(1000)) 
m <- as.matrix(df) 
m[m<0] <- 0 
df <- as.data.frame(m) 
+0

Viel. viel schneller ! Danke –

+0

Wirklich wirklich schneller! –

21

Beide ursprünglicher Ansatz und die aktuelle Antwort ein Objekt die gleiche Größe wie m erstellen (oder df), wenn m<0 Schaffung (der Matrix-Ansatz ist schneller, weil es weniger internes Kopieren ist mit [<- verglichen mit [<-.data.frame

Sie können lapply und replace, dann sind Sie auf der Suche nur auf einen Vektor oder length (nrow(df)) jedes Mal und nicht so sehr das Kopieren

df <- as.data.frame(lapply(df, function(x){replace(x, x <0,0)}) 

Der obige Code sollte sehr effizient sein.

Wenn Sie data.table verwenden, dann wird der größte Teil der Speicher (und) -Zeit-Ineffizienz des data.frame-Ansatzes entfernt. Es wäre ideal für eine große Datensituation wie Ihre.

library(data.table) 
# this really shouldn't be 
DT <- lapply(df, function(x){replace(x, x <0,0)}) 
# change to data.table 
setattr(DT, 'class', c('data.table','data.frame')) 
# or 
# DT <- as.data.table(df, function(x){replace(x, x <0,0)}) 

Sie Schlüssel auf alle Spalten einstellen könnte und dann als Referenz für die wichtigsten Werte kleiner als 0

Verwandte Themen