insertar data columna r dataframe

insertar - Convertir columnas data.frame de factores a caracteres



data frame en r (13)

Al comienzo de su marco de datos, incluya stringsAsFactors = FALSE para ignorar todos los malentendidos.

Tengo un marco de datos. Llamémosle bob :

> head(bob) phenotype exclusion GSM399350 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119- GSM399351 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119- GSM399352 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119- GSM399353 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119- GSM399354 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119- GSM399355 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-

Me gustaría concatenar las filas de este marco de datos (esta será otra pregunta). Pero mira:

> class(bob$phenotype) [1] "factor"

Las columnas de Bob son factores. Así por ejemplo:

> as.character(head(bob)) [1] "c(3, 3, 3, 6, 6, 6)" "c(3, 3, 3, 3, 3, 3)" [3] "c(29, 29, 29, 30, 30, 30)"

No empiezo a entender esto, pero supongo que estos son índices en los niveles de los factores de las columnas (de la corte del rey caractaco) de bob . No es lo que necesito.

Curiosamente puedo atravesar las columnas de bob con la mano, y hacer

bob$phenotype <- as.character(bob$phenotype)

que funciona bien. Y, después de algunos tecleos, puedo obtener un data.frame cuyas columnas son caracteres en lugar de factores. Entonces mi pregunta es: ¿cómo puedo hacer esto automáticamente? ¿Cómo convierto un data.frame con columnas de factor en un data.frame con columnas de caracteres sin tener que pasar manualmente por cada columna?

Pregunta extra: ¿por qué funciona el enfoque manual?


Esta función hace el truco

df <- stacomirtools::killfactor(df)


Esto funciona para mí - finalmente me di cuenta de una sola línea

df <- as.data.frame(lapply(df,function (y) if(class(y)=="factor" ) as.character(y) else y),stringsAsFactors=F)


La opción global

stringsAsFactors: la configuración predeterminada para los argumentos de data.frame y read.table.

puede ser algo que desee establecer en FALSE en sus archivos de inicio (por ejemplo, ~ / .Rprofile). Por favor vea help(options) .


Normalmente hago esta función aparte de todos mis proyectos. Rapido y Facil.

unfactorize <- function(df){ for(i in which(sapply(df, class) == "factor")) df[[i]] = as.character(df[[i]]) return(df) }


O puedes intentar transform :

newbob <- transform(bob, phenotype = as.character(phenotype))

Solo asegúrate de poner todos los factores que quieras convertir en personaje.

O puedes hacer algo como esto y matar todas las plagas con un solo golpe:

newbob_char <- as.data.frame(lapply(bob[sapply(bob, is.factor)], as.character), stringsAsFactors = FALSE) newbob_rest <- bob[!(sapply(bob, is.factor))] newbob <- cbind(newbob_char, newbob_rest)

No es una buena idea empujar los datos en un código como este, podría hacer la parte de sapply separado (en realidad, es mucho más fácil hacerlo así), pero entiendes el punto ... No he revisado el código. Porque no estoy en casa, así que espero que funcione! =)

Este enfoque, sin embargo, tiene un inconveniente ... debe reorganizar las columnas después, mientras que con la transform puede hacer lo que quiera, pero al costo de "escritura de código de estilo peatonal" ...

Así que hay ... =)


Otra forma es convertirlo usando aplicar.

bob2 <- apply(bob,2,as.character)

Y una mejor (la anterior es de clase ''matriz'')

bob2 <- as.data.frame(as.matrix(bob),stringsAsFactors=F)



Sé que esta respuesta es un poco tarde, pero si comprende cómo se almacenan los factores, puede evitar el uso de funciones basadas en aplicaciones para lograr esto. Lo que no implica en absoluto que las soluciones de aplicación no funcionen bien.

Los factores se estructuran como índices numéricos vinculados a una lista de "niveles". Esto se puede ver si convierte un factor a numérico. Asi que:

> fact <- as.factor(c("a","b","a","d") > fact [1] a b a d Levels: a b d > as.numeric(fact) [1] 1 2 1 3

Los números devueltos en la última línea corresponden a los niveles del factor.

> levels(fact) [1] "a" "b" "d"

Observe que los levels() devuelven una matriz de caracteres. Puede utilizar este hecho para convertir de forma fácil y compacta factores en cadenas o números como este:

> fact_character <- levels(fact)[as.numeric(fact)] > fact_character [1] "a" "b" "a" "d"

Esto también funciona para valores numéricos, siempre que envuelva su expresión en as.numeric() .

> num_fact <- factor(c(1,2,3,6,5,4)) > num_fact [1] 1 2 3 6 5 4 Levels: 1 2 3 4 5 6 > num_num <- as.numeric(levels(num_fact)[as.numeric(num_fact)]) > num_num [1] 1 2 3 6 5 4


Sólo seguí a Matt y Dirk. Si desea recrear su marco de datos existente sin cambiar la opción global, puede recrearlo con una declaración de aplicación:

bob <- data.frame(lapply(bob, as.character), stringsAsFactors=FALSE)

Esto convertirá todas las variables en "carácter" de clase, si solo desea convertir factores, consulte la solución de Marek a continuación .

Como @hadley señala, lo siguiente es más conciso.

bob[] <- lapply(bob, as.character)

En ambos casos, lapply produce una lista; sin embargo, debido a las propiedades mágicas de R, el uso de [] en el segundo caso mantiene la clase data.frame del objeto bob , eliminando así la necesidad de volver a convertir a un data.frame usando as.data.frame con el argumento stringsAsFactors = FALSE .


Si desea un nuevo cuadro de datos en bobc donde cada vector de factor en bobf se convierte en un vector de caracteres, intente esto:

bobc <- rapply(bobf, as.character, classes="factor", how="replace")

Si luego desea volver a convertirlo, puede crear un vector lógico de qué columnas son factores y utilizarlo para aplicar el factor de forma selectiva.

f <- sapply(bobf, class) == "factor" bobc[,f] <- lapply(bobc[,f], factor)


Si utilizaría el paquete data.table para las operaciones en data.frame, entonces el problema no está presente.

library(data.table) dt = data.table(col1 = c("a","b","c"), col2 = 1:3) sapply(dt, class) # col1 col2 #"character" "integer"

Si ya tiene un factor de columnas en su conjunto de datos y desea convertirlas en caracteres, puede hacer lo siguiente.

library(data.table) dt = data.table(col1 = factor(c("a","b","c")), col2 = 1:3) sapply(dt, class) # col1 col2 # "factor" "integer" upd.cols = sapply(dt, is.factor) dt[, names(dt)[upd.cols] := lapply(.SD, as.character), .SDcols = upd.cols] sapply(dt, class) # col1 col2 #"character" "integer"


Actualización: Aquí hay un ejemplo de algo que no funciona. Pensé que lo haría, pero creo que la opción stringsAsFactors solo funciona con cadenas de caracteres, deja los factores por sí solos.

Prueba esto:

bob2 <- data.frame(bob, stringsAsFactors = FALSE)

En general, siempre que tenga problemas con factores que deberían ser caracteres, hay una configuración de stringsAsFactors en algún lugar para ayudarlo (incluida una configuración global).