2012-02-27 12 views
5

Tengo data.frame que contiene varios factores y quiero cambiar el nombre de los niveles de factores para todos estos factores. Ej .:¿Cómo asignar dentro de aplicar familia?

mydf <- data.frame(col1 = as.factor(c("A","A",NA,NA)),col2 = as.factor(c("A",NA,NA,"A"))) 
mydf <- as.data.frame(lapply(mydf,addNA)) 

Tenga en cuenta que el ejemplo de la vida real tiene mucho más que sólo dos columnas. Por lo tanto me gustaría utilizar aplican para asignar otros nombres de nivel a todas estas columnas, al igual que en:

levels(mydf$col1) <- c("1","0") 

He intentado lo siguiente pero no funcionó ...

apply(mydf,1,function(x) levels(x) <- c("1","0")) 

No estoy realmente sorprendido de que no funciona, pero no tengo mejores ideas en este momento. ¿Debo usar with tal vez?

EDIT: Me di cuenta de que cometí un error al simplificar demasiado las cosas. Usé addNA para tener en cuenta el hecho de que las NA ya no deberían manejarse como NA. Por lo tanto, también quiero volver a etiquetarlos. esto no funciona con la sugerencia de Andrie y devuelve el siguiente mensaje de error:

labels = c("1", : invalid labels; length 2 should be 1 or 1 

Tenga en cuenta que he actualizado mi ejemplo df.

+0

No dice lo que quiere hacer con los niveles de NA. ¿Cambiarles el nombre a qué? – Andrie

+0

después de usar addNA Tengo los niveles 1 y . Y me gustaría que la categoría de NA se cambie a 0, al igual que eran niveles de factor ordinarios y nunca habían sido NA. –

+0

@Charles: ¿qué pasa con la etiqueta categórica? Esta es una pregunta seria. ¿Es porque es tan independiente del lenguaje? Usar el término R para categórico ('factor') no hubiera sido mejor. ¿Debo dejar todo el aspecto y por qué? –

Respuesta

8

Puede cambiar los niveles por referencia utilizando setattr() desde los paquetes bit o data.table. Esto evita la copia de todo el conjunto de datos, y puesto que usted ha dicho que tiene una gran cantidad de columnas ...

require(bit)   # Either package 
require(data.table) # 
setattr(mydf[[1]],"levels",c("1","0")) 
setattr(mydf[[2]],"levels",c("1","0")) 

que se pueden hacer de una forma sencilla for bucle que es muy rápido. Es su responsabilidad asegurarse de reemplazar el vector de niveles por un vector de la misma longitud, de lo contrario, el factor puede dejar de ser válido. Y, debes reemplazar el vector de niveles completos con este método. Hay una forma interna en data.table para reemplazar nombres de niveles particulares por referencia, pero probablemente no sea necesario ir tan lejos.

+1

¿Por qué no 'attr (mydf [[1]]," niveles ") <- c (" 1 "," 0 ")' o 'niveles (mydf [[1]]) <- c (" 1 "," 0 ")'? –

+2

@Joshua 'tracemem (mydf)' primero, vea las 4 copias (del _objeto_todo). Mantenga 'tracemem' y luego intente' setattr() ': sin copias, ninguna. Luego, da 'mydf' a 1 billón de filas y mira a los otros fallar con 'out of memory', cuando' setattr() 'funciona bien (y rápidamente). –

+0

Ah, por supuesto, porque está subconjunto el data.frame. Mis pruebas en un solo vector no crearon copias. Gracias por la aclaración. –

Cuestiones relacionadas