variable numericas numerica factor convertir categoricas r dataframe na rbind r-factor

numericas - convertir factor en variable numerica r



¿Por qué R cambia el tipo de variable al anteponer los valores de NA a un marco de datos con factores? (5)

Tengo un problema con la forma en que R coacciona los tipos de variables cuando se usa una rbind de dos data.frames con valores de NA . Ilustramos con el ejemplo:

x<-factor(sample(1:3,10,T)) y<-rnorm(10) dat<-data.frame(x,y) NAs<-data.frame(matrix(NA,ncol=ncol(dat),nrow=nrow(dat))) colnames(NAs)<-colnames(dat)

Ahora el objetivo es agregar dat y NAs mientras se mantienen los tipos de variables factor y numeric de y . Cuando doy:

dat_forward<-rbind(dat,NAs) is.factor(dat_forward$x)

esto funciona bien Sin embargo, la dirección hacia atrás con rbind falla:

dat_backward<-rbind(NAs,dat) is.factor(dat_backward$x) is.character(dat_backward$x)

Ahora x está obligado a nivel de personaje. Estoy confundido, ¿no puede permanecer el tipo de factor incluso si utilizo el otro orden de enlace? ¿Cuál sería un cambio directo en mi código para alcanzar mi objetivo?


Aquí hay una manera bastante simple de obtener las clases de columna correctas:

x <- rbind(dat[1,], NAs, dat)[-1,] str(x) # $ x: Factor w/ 3 levels "1","2","3": NA NA NA NA NA NA NA NA NA NA ... # $ y: num NA NA NA NA NA NA NA NA NA NA ...

De manera más general, si realmente necesita esto, podría crear una función similar a rbind que tome un argumento adicional que indique el data.frame a cuyas clases de columna le gustaría forzar a todas las demás columnas:

myrbind <- function(x, ..., template=x) { do.call(rbind, c(list(template[1,]), list(x), list(...)))[-1,] } str(myrbind(NAs, dat, template=dat)) # ''data.frame'': 20 obs. of 2 variables: # $ x: Factor w/ 3 levels "1","2","3": NA NA NA NA NA NA NA NA NA NA ... # $ y: num NA NA NA NA NA NA NA NA NA NA ... ## If no ''template'' argument is supplied, myrbind acts just like rbind str(myrbind(dat, NAs)) # ''data.frame'': 20 obs. of 2 variables: # $ x: Factor w/ 3 levels "1","2","3": 3 3 3 3 2 3 1 1 3 2 ... # $ y: num 0.303 1.77 -1.38 1.731 0.033 ...


Del mismo modo, podría convertir la columna en NAs para factor

NAs$x<-factor(NAs$x) dat_backward<-rbind(NAs,dat) is.factor(dat_backward$x) # TRUE is.character(dat_backward$x) # FALSE


Desde ?rbind.data.frame , leemos: "Luego toma las clases de las columnas del primer marco de datos ...". Esta es la razón por la que está viendo el asunto de la orden en su llamada a rbind .

Para obtener las clases variables de dat_forward con el orden de dat_backward , puede simplemente construir dat_forward y reordenar las filas:

dat_new = rbind(dat, NAs)[c((nrow(dat)+1):(nrow(dat)+nrow(NAs)), 1:nrow(dat)),] str(dat_new) # ''data.frame'': 20 obs. of 2 variables: # $ x: Factor w/ 3 levels "1","2","3": NA NA NA NA NA NA NA NA NA NA ... # $ y: num NA NA NA NA NA NA NA NA NA NA ...


Un enfoque sería crear NAs con los tipos de datos de columna correctos. Esto se puede hacer fácilmente con

NAs <- dat[NA,]

También puede hacer tantas filas como desee con

num.rows <- 30 NAs <- dat[NA,][1:num.rows,]


data.frame hace muchas cosas incorrectamente cuando se rbind diferentes tipos juntos, y especialmente cuando eso involucra factores. Comience a usar data.table (1.8.11+) en su lugar y no tendrá estos problemas:

library(data.table) dt1 = data.table(dat) dt2 = data.table(NAs) sapply(rbind(dt1, dt2), class) # x y # "factor" "numeric" sapply(rbind(dt2, dt1), class) # x y # "factor" "numeric"