Perché ricevo X. nei nomi delle mie colonne durante la lettura di un frame di dati?

Ho fatto una domanda a riguardo qualche mese fa , e ho pensato che la risposta avesse risolto il mio problema, ma mi sono imbattuto nuovamente nel problema e la soluzione non ha funzionato per me.

Sto importando un CSV:

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

Ecco la struttura del dataframe:

 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 ... 

Se eseguo il comando length sulla prima colonna, OrderID, ottengo questo:

 length(orders$OrderID) [1] 0 

Se eseguo la length su OrderDate, restituisce correttamente:

 length(orders$OrderDate) [1] 3331575 

Questa è una copia / incolla 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 

Ora, se read.csv il file read.csv , ma tolgo l’opzione check.names , la prima colonna del dataframe ora ha una X. all’inizio del nome.

 orders2 <- read.csv("", 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 

Funziona correttamente

La mia domanda è: perché R aggiunge una X. all’inizio del nome della prima colonna? Come puoi vedere dal file CSV, non ci sono caratteri speciali. Dovrebbe essere un semplice carico. L’aggiunta di check.names , mentre importerà il nome dal CSV, farà sì che i dati non vengano caricati correttamente per consentirmi di eseguire l’analisi.

Cosa posso fare per risolvere questo problema?

Nota a margine: mi rendo conto che questo è un aspetto secondario – sono solo più frustrato dal fatto che penso che sto caricando correttamente, ma non ottengo il risultato che mi aspettavo. Potrei rinominare la colonna usando colnames(orders)[1] <- "OrderID" , ma voglio ancora sapere perché non si carica correttamente.

read.csv() è un wrapper attorno alla più generale funzione read.table() . Quest’ultima funzione ha argomento check.names che è documentato come:

 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. 

Se l’intestazione contiene etichette che non sono sintatticamente valide allora make.names() le sostituirà con un nome valido, basato sul nome non valido, rimuovendo i caratteri non validi e eventualmente anteponendo X :

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

Questo è documentato in ?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'. 

Il comportamento che stai vedendo è del tutto coerente con il modo documentato read.table() carica nei tuoi dati. Ciò suggerirebbe di avere etichette sintatticamente non valide nella riga di intestazione del file CSV. Si noti il ​​punto in alto da ?make.names che ciò che è una lettera dipende dalle ?make.names locali del proprio sistema; Il file CSV potrebbe includere un carattere valido che verrà visualizzato dall’editor di testo, ma se R non è in esecuzione nella stessa locale in cui il carattere potrebbe non essere valido in quel caso, ad esempio?

Guarderei il file CSV e identifico tutti i caratteri non ASCII nella riga dell’intestazione; ci sono anche personaggi non visibili (o sequenze di escape; \t ?) anche nella riga di intestazione. Può accadere molto tra la lettura nel file con i nomi non validi e la visualizzazione nella console che potrebbe mascherare i caratteri non validi, quindi non prendere il fatto che non mostra nulla di sbagliato senza check.names come ad indicare che il file è OK.

Anche la pubblicazione dell’output di sessionInfo() sarebbe utile.

Ho appena trovato questo problema ed è stato per un semplice motivo. Avevo etichette che iniziavano con un numero e R aggiungeva una X davanti a tutte. Penso che R sia confuso con un numero nell’intestazione e applica una lettera per differenziare dai valori.

Quindi, “3_in” è diventato “X3_in” ecc. Ho risolto passando l’etichetta a “in_3” e il problema è stato risolto.

Spero che questo aiuti qualcuno.

Ho trovato un problema simile e volevo condividere le seguenti righe di codice per correggere i nomi delle colonne. Certamente non perfetto, dal momento che una programmazione pulita nel dritto sarebbe meglio, ma forse utile come punto di partenza per qualcuno come approccio rapido e sporco. (Mi sarebbe piaciuto aggiungerli come commento alla domanda di Ryan / risposta di Gavin, ma la mia reputazione non è abbastanza alta, quindi ho dovuto postare una risposta aggiuntiva – scusa).

Nel mio caso, diverse fasi di scrittura e lettura dei dati hanno prodotto una o più colonne denominate “X”, X.1 “, … contenenti contenuti nella colonna X e numeri di riga nelle colonne X.1, …-. Nel mio caso il contenuto della X-column dovrebbe essere usato come nome di riga e le altre X.1, …- colonne dovrebbero essere cancellate.

 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) } 

Ho risolto un problema simile includendo row.names = FALSE come argomento nella funzione write.csv. write.csv includeva i nomi delle righe come una colonna senza nome nel file CSV e read.csv stava nominando quella colonna ‘X’ quando leggeva il file CSV.