2012-05-04 9 views
40

Pedí un question about this a few months back, y pensé que la respuesta había resuelto mi problema, pero me encontré con el problema otra vez y la solución no funcionó para mí.X. en los nombres de mi columna de un marco de datos R

estoy importar un CSV:

orders <- read.csv("<file_location>", sep=",", header=T, check.names = FALSE) 

Aquí está la estructura de la trama de datos:

str(orders) 

'data.frame': 3331575 obs. of 2 variables: 
$ OrderID : num -2034590217 -2034590216 -2031892773 -2031892767 -2021008573 ... 
$ OrderDate: Factor w/ 402 levels "2010-10-01","2010-10-04",..: 263 263 269 268 301 300 300 300 300 300 ... 

Si funciono con el comando length en la primera columna, IdPedido, me sale esto:

length(orders$OrderID) 
[1] 0 

Si ejecuto el length en OrderDate, devuelve c orrectly:

length(orders$OrderDate) 
[1] 3331575 

Este es un copiar/pegar del head del CSV.

OrderID,OrderDate 
-2034590217,2011-10-14 
-2034590216,2011-10-14 
-2031892773,2011-10-24 
-2031892767,2011-10-21 
-2021008573,2011-12-08 
-2021008572,2011-12-07 
-2021008571,2011-12-07 
-2021008570,2011-12-07 
-2021008569,2011-12-07 

Ahora, si volver a ejecutar el read.csv, pero llevan a cabo la opción check.names, la primera columna de la dataframe cuenta ahora con una X en el inicio del nombre.

orders2 <- read.csv("<file_location>", sep=",", header=T) 

str(orders2) 

'data.frame': 3331575 obs. of 2 variables: 
$ X.OrderID: num -2034590217 -2034590216 -2031892773 -2031892767 -2021008573 ... 
$ OrderDate: Factor w/ 402 levels "2010-10-01","2010-10-04",..: 263 263 269 268 301 300 300 300 300 300 ... 

length(orders$X.OrderID) 
[1] 3331575 

Esto funciona correctamente.

Mi pregunta es ¿por qué R agrega una X. al principio del primer nombre de columna? Como puede ver en el archivo CSV, no hay caracteres especiales. Debe ser una carga simple. Agregar check.names, aunque importará el nombre del CSV, hará que los datos no se carguen correctamente para que realice el análisis.

¿Qué puedo hacer para solucionarlo?

Nota al margen: me doy cuenta de que esto es poco importante. Estoy más frustrado por el hecho de que creo que estoy cargando correctamente, pero sin obtener el resultado que esperaba. Podría cambiar el nombre de la columna usando colnames(orders)[1] <- "OrderID", pero aún quiero saber por qué no se carga correctamente.

+0

¿Puedes cortar y pegar el siguiente outp uts: 'cabeza (pedidos)' y 'cabeza (pedidos2)'? –

+3

Tengo más curiosidad por ver el archivo csv sin formato real. ¿Puedes publicarlo en alguna parte y proporcionar un enlace para que podamos descargarlo e intentar reproducir este comportamiento? Cualquiera que sea el problema, supongo que la respuesta está en la estructura y el contenido precisos del archivo. – joran

+0

No obtengo el pedido, pero luego el 'length (orders $ OrderID) [1] 0' –

Respuesta

54

read.csv() es un envoltorio alrededor de la función más general read.table(). Esta última función tiene argumento check.names que se documenta como:

check.names: logical. If ‘TRUE’ then the names of the variables in the 
     data frame are checked to ensure that they are syntactically 
     valid variable names. If necessary they are adjusted (by 
     ‘make.names’) so that they are, and also to ensure that there 
     are no duplicates. 

Si su cabecera contiene etiquetas que no son sintácticamente válida, entonces make.names() los reemplazará con un nombre válido, basado en el nombre no válido, la eliminación no válido personajes y posiblemente anteponiendo X:

R> make.names("$Foo") 
[1] "X.Foo" 

Esto está documentado en ?make.names:

Details: 

    A syntactically valid name consists of letters, numbers and the 
    dot or underline characters and starts with a letter or the dot 
    not followed by a number. Names such as ‘".2way"’ are not valid, 
    and neither are the reserved words. 

    The definition of a _letter_ depends on the current locale, but 
    only ASCII digits are considered to be digits. 

    The character ‘"X"’ is prepended if necessary. All invalid 
    characters are translated to ‘"."’. A missing value is translated 
    to ‘"NA"’. Names which match R keywords have a dot appended to 
    them. Duplicated values are altered by ‘make.unique’. 

El comportamiento que está viendo es totalmente coherente con la manera documentada read.table() cargas en sus datos. Eso sugeriría que tiene etiquetas sinápticas sintácticamente en la fila del encabezado de su archivo CSV.Tenga en cuenta el punto anterior de ?make.names que lo que es una letra depende de la configuración regional de su sistema; El archivo CSV puede incluir un carácter válido que se mostrará en el editor de texto, pero si R no se está ejecutando en la misma configuración regional, ese carácter puede no ser válido allí, por ejemplo.

Me gustaría ver el archivo CSV e identificar cualquier carácter que no sea ASCII en la línea del encabezado; posiblemente hay caracteres no visibles (o secuencias de escape; \t?) en la fila del encabezado también. Mucho puede estar sucediendo entre leer en el archivo los nombres no válidos y mostrarlo en la consola, lo que podría enmascarar los caracteres no válidos, por lo que no debe tomar en cuenta que no muestra nada incorrecto sin check.names como indicando que el archivo está OK.

Publicar la salida de sessionInfo() también sería útil.

+0

Buena respuesta Gavin +1 Me pregunto si hay un espacio delante del nombre del encabezado como 'make.names (" Foo ")' crea '" X.Foo "' también. –

+0

No, no es un espacio como lo probé [Aquí está el enlace a la csv] (http://dl.dropbox.com/u/61803503/TEST.csv) y aquí está el código: 'x <-" http: //dl.dropbox.com/u/61803503/TEST.csv "; (dat <-read.csv (url (x), header = TRUE)) 'y un espacio al frente o punto no lo afecta, pero el' $ 'y', 'do. –

+0

¿Es posible usar un carácter diferente en lugar de 'X'? – Dan

8

Acabo de encontrar este problema y fue por una simple razón. Tenía etiquetas que comenzaban con un número, y R agregaba una X delante de todas. Creo que R se confunde con un número en el encabezado y se aplica una letra para diferenciar de los valores.

Entonces, "3_in" se convirtió en "X3_in", etc ... Lo resolví cambiando la etiqueta a "in_3" y se resolvió el problema.

Espero que esto ayude a alguien.

+1

Gracias Matt. ¿Cómo eliminaste sistemáticamente la "x"? y anexar todas las columnas con "in_"? –

3

Me encontré con un problema similar y quería compartir las siguientes líneas de código para corregir los nombres de las columnas. Ciertamente no es perfecto, ya que la programación limpia en el golpe de derecha sería mejor, pero quizás útil como punto de partida para alguien tan rápido y sucio. (Me hubiera gustado agregarlos como comentario a la pregunta de Ryan/la respuesta de Gavin, pero mi reputación no es lo suficientemente alta, así que tuve que publicar una respuesta adicional, lo siento).

En mi caso, varios pasos de escritura y lectura de datos produjeron una o más columnas llamadas "X", X.1 ", ... que contienen contenido en la columna X y números de fila en la X.1, .. .-columnas. En mi caso, el contenido de los X-columna se debe utilizar como nombres de las filas y la otra X.1, ...- columnas deberían suprimirse.

Correct_Colnames <- function(df) { 

delete.columns <- grep("(^X$)|(^X\\.)(\\d+)($)", colnames(df), perl=T) 

    if (length(delete.columns) > 0) { 

    row.names(df) <- as.character(df[, grep("^X$", colnames(df))]) 
    #other data types might apply than character or 
    #introduction of a new separate column might be suitable 

    df <- df[,-delete.columns] 

    colnames(df) <- gsub("^X", "", colnames(df)) 
    #X might be replaced by different characters, instead of being deleted 
    } 

    return(df) 
} 
0

he resuelto un problema similar mediante la inclusión row.names = FALSE como argumento en la función write.csv. write.csv incluía los nombres de las filas como una columna sin nombre en el archivo CSV y read.csv nombraba esa columna 'X' cuando leía el archivo CSV.

Cuestiones relacionadas