2010-07-16 100 views
6

Estoy seguro de que esta es una pregunta muy básica:En R, ¿cómo colapsar categorías o recategorizar variables?

En RI tienen 600.000 variables categóricas - cada uno de los cuales se clasifica como "0", "1" o "2"

Lo que le gustaría do es colapsar "1" y "2" y dejar "0" por sí mismo, de modo que después de volver a categorizar "0" = "0"; "1" = "1" y "2" = "1" --- al final solo quiero "0" y "1" como categorías para cada una de las variables.

Además, si es posible, prefiero no crear 600,000 nuevas variables, si puedo reemplazar las variables existentes con los nuevos valores que serían geniales.

¿Cuál sería la mejor manera de hacerlo?

Gracias!

Respuesta

4

hay una función recode en el paquete car (Companion Aplicada Regresión):

require("car")  
recode(x, "c('1','2')='1'; else='0'") 

o para su caso en la llanura R:

> x <- factor(sample(c("0","1","2"), 10, replace=TRUE)) 
> x 
[1] 1 1 1 0 1 0 2 0 1 0 
Levels: 0 1 2 
> factor(pmin(as.numeric(x), 2), labels=c("0","1")) 
[1] 1 1 1 0 1 0 1 0 1 0 
Levels: 0 1 

Actualización: recodificar todas las columnas categóricas de un marco de datos tmp puede usar el siguiente

recode_fun <- function(x) factor(pmin(as.numeric(x), 2), labels=c("0","1")) 
require("plyr") 
catcolwise(recode_fun)(tmp) 
+0

Gracias por la respuesta! Así es como lo estoy aplicando específicamente a mis datos. Mis datos son en forma de un data.frame, que me gustaría mantener: data <- read.table ("k.csv", header = TRUE, sep = ",") dta <- data [ , 1: 30] col = dim (dta) [2] para (y en 1: col) { py <- factor (pmin (as.data.frame (dta [, y]), 2) , labels = c ("0", "1")) py } Por supuesto que resulta en un error - Estoy seguro de que no lo estoy aplicando correctamente – CCA

9

recode() es un poco exagerado para esto. Su caso depende de cómo está codificado actualmente. Digamos que tu variable es x.

Si es numérico

x <- ifelse(x>1, 1, x) 

si es de carácter

x <- ifelse(x=='2', '1', x) 

si es el factor con niveles 0,1,2

levels(x) <- c(0,1,1) 

Cualquiera de los que se pueden aplicar los datos a través de una marco dta a la variable x en su lugar. Por ejemplo...

dta$x <- ifelse(dta$x > 1, 1, dta$x) 

O, varias columnas de un marco

df[,c('col1','col2'] <- sapply(df[,c('col1','col2'], FUN = function(x) ifelse(x==0, x, 1)) 
12

Me parece que este es aún más genérico utilizando factor(new.levels[x]):

> x <- factor(sample(c("0","1","2"), 10, replace=TRUE)) 
> x 
[1] 0 2 2 2 1 2 2 0 2 1 
Levels: 0 1 2 
> new.levels<-c(0,1,1) 
> x <- factor(new.levels[x]) 
> x 
[1] 0 1 1 1 1 1 1 0 1 1 
Levels: 0 1 

los nuevos niveles de vectores debe la misma longitud que el número de niveles en x, por lo que puede hacer recodes más complicados también con cadenas y NA, por ejemplo,

x <- factor(c("old", "new", NA)[x]) 
> x 
[1] old <NA> <NA> <NA> new <NA> <NA> old 
[9] <NA> new  
Levels: new old 
0

Tenga en cuenta que si lo que desea que los resultados sean 0-1 variables binarias, se puede renunciar por completo factores:

f <- sapply(your.data.frame, is.factor) 
your.data.frame[f] <- lapply(your.data.frame[f], function(x) x != "0") 

La segunda línea también se puede escribir de forma más sucinta (pero posiblemente más críptica) como

your.data.frame[f] <- lapply(your.data.frame[f], `!=`, "0") 

Esto convierte su factores en una serie de variables lógicas, con la asignación de "0" a FALSE y cualquier otra asignación a TRUE. FALSE y TRUE serán tratados como 0 y 1 por la mayoría del código, que a su vez debería dar esencialmente el mismo resultado en un análisis que usar un factor con niveles "0" y "1". De hecho, si no se dan el mismo resultado, que sería puesto en duda la exactitud del análisis ....

0

usted podría utilizar la función rec del paquete sjmisc, que puede recodificar una de datos completa marco a la vez (dado que todas las variables tienen al menos los mismos valores de recodificación).

library(sjmisc) 
mydf <- data.frame(a = sample(0:2, 10, T), 
        b = sample(0:2, 10, T), 
        c = sample(0:2, 10, T)) 

> mydf 
    a b c 
1 1 1 0 
2 1 0 1 
3 0 2 0 
4 0 1 0 
5 1 0 0 
6 2 1 1 
7 0 1 1 
8 2 1 2 
9 1 1 2 
10 2 0 1 

mydf <- rec(mydf, "0=0; 1,2=1") 

    a b c 
1 1 1 0 
2 1 0 1 
3 0 1 0 
4 0 1 0 
5 1 0 0 
6 1 1 1 
7 0 1 1 
8 1 1 1 
9 1 1 1 
10 1 0 1 
0

Me gustó la función en dplyr que puede recodificar valores rápidamente.

library(dplyr) 
df$x <- recode(df$x, old = "new") 

Espero que esto ayude :)

Cuestiones relacionadas