transformar studio recodificar numericas funcion factor datos convertir categorizar categoricas agrupar r

numericas - recodificar variables en r studio



Expandir automáticamente un factor R en una colección de variables de indicador 1/0 para cada nivel de factor (8)

Acabo de encontrar este viejo hilo y pensé que agregaría una función que utiliza ade4 para tomar un marco de datos que consta de factores y / o datos numéricos y devuelve un marco de datos con factores como códigos ficticios.

dummy <- function(df) { NUM <- function(dataframe)dataframe[,sapply(dataframe,is.numeric)] FAC <- function(dataframe)dataframe[,sapply(dataframe,is.factor)] require(ade4) if (is.null(ncol(NUM(df)))) { DF <- data.frame(NUM(df), acm.disjonctif(FAC(df))) names(DF)[1] <- colnames(df)[which(sapply(df, is.numeric))] } else { DF <- data.frame(NUM(df), acm.disjonctif(FAC(df))) } return(DF) }

Vamos a intentarlo.

df <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c("red","blue","green","red"), x=rnorm(4)) dummy(df) df2 <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c("red","blue","green","red")) dummy(df2)

Tengo un marco de datos R que contiene un factor que quiero "expandir", de modo que para cada nivel de factor, hay una columna asociada en un nuevo marco de datos, que contiene un indicador 1/0. Por ejemplo, supongamos que tengo:

df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4))

Yo quiero:

df.desired <- data.frame(foo = c(1,1,0,0), bar=c(0,0,1,1), ham=c(1,2,3,4))

Debido a que para ciertos análisis para los cuales necesita tener un marco de datos completamente numérico (por ejemplo, análisis de componentes principales), pensé que esta característica podría estar incorporada. Escribir una función para hacer esto no debería ser demasiado difícil, pero puedo prever algunas desafíos relacionados con los nombres de columna y si algo existe ya, preferiría usar eso.


Aquí hay una manera más clara de hacerlo. Uso model.matrix para crear las variables booleanas ficticias y luego fusionarlas nuevamente en el marco de datos original.

df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4)) df.original # eggs ham # 1 foo 1 # 2 foo 2 # 3 bar 3 # 4 bar 4 # Create the dummy boolean variables using the model.matrix() function. > mm <- model.matrix(~eggs-1, df.original) > mm # eggsbar eggsfoo # 1 0 1 # 2 0 1 # 3 1 0 # 4 1 0 # attr(,"assign") # [1] 1 1 # attr(,"contrasts") # attr(,"contrasts")$eggs # [1] "contr.treatment" # Remove the "eggs" prefix from the column names as the OP desired. colnames(mm) <- gsub("eggs","",colnames(mm)) mm # bar foo # 1 0 1 # 2 0 1 # 3 1 0 # 4 1 0 # attr(,"assign") # [1] 1 1 # attr(,"contrasts") # attr(,"contrasts")$eggs # [1] "contr.treatment" # Combine the matrix back with the original dataframe. result <- cbind(df.original, mm) result # eggs ham bar foo # 1 foo 1 0 1 # 2 foo 2 0 1 # 3 bar 3 1 0 # 4 bar 4 1 0 # At this point, you can select out the columns that you want.


Necesitaba una función para ''explotar'' factores que es un poco más flexible, e hice una basada en la función acm.disjonctif del paquete ade4. Esto le permite elegir los valores desglosados, que son 0 y 1 en acm.disjonctif. Solo explota factores que tienen ''pocos'' niveles. Las columnas numéricas se conservan.

# Function to explode factors that are considered to be categorical, # i.e., they do not have too many levels. # - data: The data.frame in which categorical variables will be exploded. # - values: The exploded values for the value being unequal and equal to a level. # - max_factor_level_fraction: Maximum number of levels as a fraction of column length. Set to 1 to explode all factors. # Inspired by the acm.disjonctif function in the ade4 package. explode_factors <- function(data, values = c(-0.8, 0.8), max_factor_level_fraction = 0.2) { exploders <- colnames(data)[sapply(data, function(col){ is.factor(col) && nlevels(col) <= max_factor_level_fraction * length(col) })] if (length(exploders) > 0) { exploded <- lapply(exploders, function(exp){ col <- data[, exp] n <- length(col) dummies <- matrix(values[1], n, length(levels(col))) dummies[(1:n) + n * (unclass(col) - 1)] <- values[2] colnames(dummies) <- paste(exp, levels(col), sep = ''_'') dummies }) # Only keep numeric data. data <- data[sapply(data, is.numeric)] # Add exploded values. data <- cbind(data, exploded) } return(data) }


Si su marco de datos solo está compuesto de factores (o está trabajando en un subconjunto de variables que son todos factores), también puede usar la función ade4 paquete ade4 :

R> library(ade4) R> df <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c("red","blue","green","red")) R> acm.disjonctif(df) eggs.bar eggs.foo ham.blue ham.green ham.red 1 0 1 0 0 1 2 0 1 1 0 0 3 1 0 0 1 0 4 1 0 0 0 1

No es exactamente el caso que está describiendo, pero también puede ser útil ...


Una class.ind entrada class.ind del paquete nnet

library(nnet) with(df.original, data.frame(class.ind(eggs), ham)) bar foo ham 1 0 1 1 2 0 1 2 3 1 0 3 4 1 0 4


Una forma rápida de usar el paquete reshape2 :

require(reshape2) > dcast(df.original, ham ~ eggs, length) Using ham as value column: use value_var to override. ham bar foo 1 1 0 1 2 2 0 1 3 3 1 0 4 4 1 0

Tenga en cuenta que esto produce precisamente los nombres de columna que desea.


Use la función model.matrix :

model.matrix( ~ Species - 1, data=iris )


probablemente la variable dummy sea similar a la que desee. Entonces, model.matrix es útil:

> with(df.original, data.frame(model.matrix(~eggs+0), ham)) eggsbar eggsfoo ham 1 0 1 1 2 0 1 2 3 1 0 3 4 1 0 4