Tengo un archivo csv donde algunos de los valores numéricos se expresan como cadenas con comas como separador de miles, por ejemplo, en "1,513"
lugar de 1513
. ¿Cuál es la forma más sencilla de leer los datos en R?
Puedo usar read.csv(..., colClasses="character")
, pero luego tengo que quitar las comas de los elementos relevantes antes de convertir esas columnas a numéricas, y no puedo encontrar una manera ordenada de hacerlo.
setAs("character", "logical.Y.N", function(from) c(Y=TRUE,N=FALSE)[from] )
).setClass("num.with.commas")
osuppresMessage(setAs(.....))
para evitar el mensaje sobre la clase perdida.Quiero usar R en lugar de preprocesar los datos, ya que facilita la revisión de los datos. Siguiendo la sugerencia de Shane de usar
gsub
, creo que esto es lo más ordenado que puedo hacer:fuente
Esta pregunta tiene varios años, pero me encontré con ella, lo que significa que tal vez otros lo hagan.
La
readr
biblioteca / paquete tiene algunas características interesantes. Uno de ellos es una buena forma de interpretar columnas "desordenadas", como estas.Esto produce
Fuente: marco de datos local [4 x 1]
Un punto importante al leer en archivos: o tiene que preprocesar, como el comentario anterior
sed
, o tiene que procesar mientras lee . A menudo, si intenta arreglar las cosas después de los hechos, se hacen algunas suposiciones peligrosas que son difíciles de encontrar. (Es por eso que las limas planas son tan malas en primer lugar).Por ejemplo, si no hubiera marcado el
col_types
, habría obtenido esto:(Observe que ahora es un
chr
(character
) en lugar de anumeric
.)O, lo que es más peligroso, si fuera lo suficientemente largo y la mayoría de los elementos iniciales no contuvieran comas:
(de modo que los últimos elementos parezcan :)
¡Entonces encontrarás problemas para leer esa coma!
fuente
una
dplyr
solución usandomutate_all
y tuberíasdi que tienes lo siguiente:
y desea eliminar las comas de las variables de año X2014-X2016 y convertirlas en numéricas. también, digamos que X2014-X2016 se leen como factores (predeterminado)
mutate_all
aplica la (s) función (es) dentrofuns
de las columnas especificadasLo hice secuencialmente, una función a la vez (si usa múltiples funciones adentro,
funs
entonces crea columnas adicionales innecesarias)fuente
mutate_each
es obsoleto. ¿Quieres actualizar tu respuesta conmutate_at
o similar?"Preproceso" en R:
Se puede usar
readLines
en untextConnection
. Luego, elimine solo las comas que están entre los dígitos:También es útil saber, pero no directamente relevante para esta pregunta, que las comas como separadores decimales pueden ser manejadas por read.csv2 (automágicamente) o read.table (con la configuración del parámetro 'dec').
Editar: Más tarde descubrí cómo usar colClasses diseñando una nueva clase. Ver:
¿Cómo cargar df con separador 1000 en R como clase numérica?
fuente
Si el número está separado por "." y decimales por "," (1.200.000,00) al llamar
gsub
debeset fixed=TRUE as.numeric(gsub(".","",y,fixed=TRUE))
fuente
Una forma muy conveniente es la
readr::read_delim
familia. Tomando el ejemplo de aquí: Importando csv con múltiples separadores en R , puede hacerlo de la siguiente manera:Lo que da como resultado el resultado esperado:
fuente
Usando la función read_delim, que es parte de la biblioteca readr , puede especificar un parámetro adicional:
* El punto y coma en la segunda línea significa que read_delim leerá los valores separados por punto y coma de csv.
Esto ayudará a leer todos los números con coma como números adecuados.
Saludos
Mateusz Kania
fuente
También podemos usar
readr::parse_number
, aunque las columnas deben ser caracteres. Si queremos aplicarlo para varias columnas, podemos recorrer las columnas usandolapply
O use
mutate_at
fromdplyr
para aplicarlo a variables específicas.datos
fuente
Creo que el preprocesamiento es el camino a seguir. Puede usar Notepad ++ que tiene una opción de reemplazo de expresión regular.
Por ejemplo, si su archivo fuera así:
Luego, puede usar la expresión regular
"([0-9]+),([0-9]+)"
y reemplazarla con\1\2
Entonces podrías usar
x <- read.csv(file="x.csv",header=FALSE)
para leer el archivo.fuente