2012-10-11 32 views
17

Tengo un marco de datos de 150,000 filas con 2,000 columnas que contienen valores, algunos de los cuales son negativos. Estoy reemplazando esos valores negativos por 0, pero es extremadamente lento hacerlo (~ 60 minutos o más).Valores de sustitución rápida en el marco de datos en R

df[df < 0] = 0

donde df[,1441:1453] parece (todas las columnas/valores numéricos):

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 

¿Hay una manera de acelerar dicho proceso, por ejemplo, la manera en que yo estoy haciendo es absolutamente lento, y hay un enfoque más rápido para esto? Gracias.

+0

150.000 filas x 2000 columnas: Esto es correcto –

+0

Puede usted por favor [mostrarnos] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) cómo son tus datos? ¿Son todas las columnas numéricas? – Roland

Respuesta

29

Intente transformar su df en una matriz.

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

Mucho. mucho mas rápido ! Gracias –

+0

¡Realmente más rápido! –

21

Tanto su enfoque original y la respuesta actual crear un objeto del mismo tamaño que m (o df) al crear m<0 (el enfoque de la matriz es más rápido porque hay menos copia interna con [<- comparación con [<-.data.frame

puede utilizar lapply y replace, a continuación, sólo se está buscando en un vector o length (nrow(df)) cada vez y no copiar tanto

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

El código anterior debería ser bastante eficaz.

Si usa data.table, la mayor parte de la ineficacia del tiempo de memoria (y) del enfoque data.frame se elimina. Sería ideal para una situación de datos de gran tamaño como la tuya.

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)}) 

Usted puede configurar teclas en todas las columnas y volviendo a poner por referencia a los valores clave de menos de 0

Cuestiones relacionadas