Cuando convierto un factor a un valor numérico o entero, obtengo los códigos de nivel subyacentes, no los valores como números.
f <- factor(sample(runif(5), 20, replace = TRUE))
## [1] 0.0248644019011408 0.0248644019011408 0.179684827337041
## [4] 0.0284090070053935 0.363644931698218 0.363644931698218
## [7] 0.179684827337041 0.249704354675487 0.249704354675487
## [10] 0.0248644019011408 0.249704354675487 0.0284090070053935
## [13] 0.179684827337041 0.0248644019011408 0.179684827337041
## [16] 0.363644931698218 0.249704354675487 0.363644931698218
## [19] 0.179684827337041 0.0284090070053935
## 5 Levels: 0.0248644019011408 0.0284090070053935 ... 0.363644931698218
as.numeric(f)
## [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2
as.integer(f)
## [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2
Tengo que recurrir a paste
para obtener los valores reales:
as.numeric(paste(f))
## [1] 0.02486440 0.02486440 0.17968483 0.02840901 0.36364493 0.36364493
## [7] 0.17968483 0.24970435 0.24970435 0.02486440 0.24970435 0.02840901
## [13] 0.17968483 0.02486440 0.17968483 0.36364493 0.24970435 0.36364493
## [19] 0.17968483 0.02840901
¿Hay una mejor manera de convertir un factor a numérico?
attributes(f)
), por lo que no creo que haya nada maloas.numeric(paste(f))
. Quizás sería mejor pensar por qué (en el contexto específico) está obteniendo un factor en primer lugar, y tratar de detenerlo. Por ejemplo, ¿eldec
argumento estáread.table
configurado correctamente?df %>% convert(num(column))
. O si tiene un vector de factores que puede usaras_reliable_num(factor_vector)
Respuestas:
Vea la sección de Advertencia de
?factor
:Las preguntas frecuentes sobre R tienen consejos similares .
¿Por qué es
as.numeric(levels(f))[f]
más eficiente queas.numeric(as.character(f))
?as.numeric(as.character(f))
es efectivoas.numeric(levels(f)[f])
, por lo que está realizando la conversión alength(x)
valores numéricos en lugar denlevels(x)
valores. La diferencia de velocidad será más evidente para los vectores largos con pocos niveles. Si los valores son en su mayoría únicos, no habrá mucha diferencia en la velocidad. Independientemente de cómo realice la conversión, es poco probable que esta operación sea el cuello de botella en su código, así que no se preocupe demasiado por eso.Algunos horarios
fuente
R tiene varias funciones de conveniencia (no documentadas) para convertir factores:
as.character.factor
as.data.frame.factor
as.Date.factor
as.list.factor
as.vector.factor
Pero molestamente, no hay nada para manejar el factor -> conversión numérica . Como una extensión de la respuesta de Joshua Ulrich, sugeriría superar esta omisión con la definición de su propia función idiomática:
que puede almacenar al comienzo de su secuencia de comandos, o incluso mejor en su
.Rprofile
archivo.fuente
as.integer(factor)
devuelva los códigos enteros subyacentes (como se muestra en la sección de ejemplos de?factor
). Probablemente esté bien definir esta función en su entorno global, pero puede causar problemas si realmente la registra como un método S3.factor->numeric
conversión mucho antes de darse cuenta de que en realidad es un defecto de R: Con un poco de función de conveniencia debería estar disponible ... Llamarloas.numeric.factor
tiene sentido para mí, pero tu caso es distinto.v=NA;as.numeric.factor(v)
ov='something';as.numeric.factor(v)
, entonces debería, de lo contrario tienes algo extraño en alguna parte.La forma más fácil sería usar la
unfactor
función del paquete varhandleEste ejemplo puede ser un comienzo rápido:
fuente
unfactor
función convierte primero al tipo de datos de caracteres y luego vuelve a convertir a numérico. Escribaunfactor
en la consola y podrá verlo en el medio de la función. Por lo tanto, en realidad no ofrece una solución mejor que la que ya tenía el autor de la pregunta.unfactor
función se encarga de cosas que no se pueden convertir a numérico. Mira los ejemplos enhelp("unfactor")
library("varhandle")
primero debe cargar el paquete ( ) (¡como mencioné en la primera línea de mi respuesta!)as.numeric()
yas.character()
en un orden incorrecto;) Lo que hace su fragmento de código es convertir el índice de nivel del factor en una matriz de caracteres, así que lo que tendrá en el y es un vector de caracteres que contiene algunos números que alguna vez se asignaron a cierto nivel de su factor. Las funciones en ese paquete están ahí para evitar estas confusionesNota: esta respuesta en particular no es para convertir factores de valor numérico a numéricos, es para convertir factores categóricos a sus números de nivel correspondientes.
Cada respuesta en esta publicación no pudo generar resultados para mí, se estaban generando NA.
Lo que funcionó para mí es esto:
fuente
y<-factor(c("5","15","20","2")); unclass(y) %>% as.numeric
Esto devuelve 4,1,3,2, no 5,15,20,2. Esto parece información incorrecta.as.numeric(y)
debería haber funcionado bien, sin necesidad deunclass()
. Pero de nuevo, de eso no se trataba esta pregunta. Esta respuesta no es apropiada aquí.Es posible solamente en el caso en que las etiquetas de los factores coinciden con los valores originales. Lo explicaré con un ejemplo.
Suponga que los datos son vectores
x
:Ahora crearé un factor con cuatro etiquetas:
1)
x
es con tipo doble,f
es con tipo entero. Esta es la primera pérdida inevitable de información. Los factores siempre se almacenan como enteros.2) No es posible volver a los valores originales (10, 20, 30, 40) que solo están
f
disponibles. Podemos ver quef
solo contiene valores enteros 1, 2, 3, 4 y dos atributos: la lista de etiquetas ("A", "B", "C", "D") y el atributo de clase "factor". Nada mas.Para volver a los valores originales, debemos conocer los valores de los niveles utilizados para crear el factor. En este caso
c(10, 20, 30, 40)
. Si conocemos los niveles originales (en el orden correcto), podemos volver a los valores originales.Y esto solo funcionará en caso de que se hayan definido etiquetas para todos los valores posibles en los datos originales.
Entonces, si necesita los valores originales, debe conservarlos. De lo contrario, existe una alta probabilidad de que no sea posible volver a ellos solo por un factor.
fuente
Puede usar
hablar::convert
si tiene un marco de datos. La sintaxis es fácil:Muestra df
Solución
te dio:
O si desea que una columna sea entera y una numérica:
resultados en:
fuente
Parece que la solución como.numeric (niveles (f)) [f] ya no funciona con R 4.0.
Solución alternativa:
fuente
De las muchas respuestas que pude leer, la única forma dada fue expandir el número de variables de acuerdo con el número de factores. Si tiene una "mascota" variable con los niveles "perro" y "gato", terminaría con pet_dog y pet_cat.
En mi caso, quería quedarme con el mismo número de variables, simplemente traduciendo la variable del factor a una numérica, de manera que pueda aplicarse a muchas variables con muchos niveles, de modo que cat = 1 y dog = 0, por ejemplo.
Encuentre la solución correspondiente a continuación:
fuente
tarde al juego, accidentalmente, me encontré
trimws()
convertido latafactor(3:5)
ac("3","4","5")
. Entonces puedes llamaras.numeric()
. Es decir:fuente
trimws
más deas.character
como se describe en la respuesta aceptada? Me parece que, a menos que en realidad tuviera un espacio en blanco que necesitara eliminar,trimws
solo va a hacer un montón de trabajo innecesario de expresión regular para devolver el mismo resultado.