Pourquoi est-ce que je reçois X. dans mes noms de colonne lors de la lecture d’un bloc de données?

J’ai posé une question à ce sujet il y a quelques mois , et je pensais que la réponse avait résolu mon problème, mais j’ai de nouveau rencontré le problème et la solution n’a pas fonctionné pour moi.

Je importe un fichier CSV:

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

Voici la structure du 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 ... 

Si je lance la commande length sur la première colonne, OrderID, j’obtiens ceci:

 length(orders$OrderID) [1] 0 

Si je lance la length sur OrderDate, elle retourne correctement:

 length(orders$OrderDate) [1] 3331575 

Ceci est un copier / coller de la head du 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 

Maintenant, si je ré-exécute le read.csv , mais que vous check.names option check.names , la première colonne du dataframe maintenant un X au début du nom.

 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 

Cela fonctionne correctement.

Ma question est la suivante: pourquoi R ajoute-t-il un X au début du nom de la première colonne? Comme vous pouvez le voir sur le fichier CSV, il n’y a pas de caractères spéciaux. Ce devrait être une simple charge. L’ajout de check.names , alors que le nom sera importé à partir du check.names CSV, entraînera le chargement incorrect des données pour que je puisse effectuer une parsing.

Que puis-je faire pour résoudre ce problème?

Note: je me rends compte que c’est une mineure – je suis juste plus frustré par le fait que je pense que je charge correctement, sans obtenir le résultat escompté. Je pourrais renommer la colonne en utilisant colnames(orders)[1] <- "OrderID" , mais je veux quand même savoir pourquoi elle ne se charge pas correctement.

read.csv() est un wrapper autour de la fonction read.table() plus générale. Cette dernière fonction a un argument check.names documenté comme check.names :

 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 votre en-tête contient des étiquettes qui ne sont pas syntaxiquement valides, make.names() les remplacera par un nom valide, basé sur le nom non valide, en supprimant les caractères non valides et éventuellement en ajoutant X :

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

Ceci est documenté dans ?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'. 

Le comportement que vous read.table() est tout à fait conforme à la manière documentée que read.table() charge dans vos données. Cela suggère que vous avez des étiquettes syntaxiquement invalides dans la ligne d’en-tête de votre fichier CSV. Notez le point ci-dessus de ?make.names que ce qui est une lettre dépend de la locale de votre système; Le fichier CSV peut inclure un caractère valide que votre éditeur de texte affichera, mais si R ne s’exécute pas dans les mêmes parameters régionaux, ce caractère peut ne pas être valide, par exemple?

Je regarderais le fichier CSV et identifierais tous les caractères non-ASCII dans la ligne d’en-tête; il y a éventuellement des caractères non visibles (ou des séquences d’échappement; \t ?) dans la ligne d’en-tête également. Il se peut que beaucoup de choses se passent entre la lecture dans le fichier avec les noms non valides et l’affichage dans la console qui pourrait masquer les caractères non valides. check.names comme indiquant que le fichier est OK.

Publier la sortie de sessionInfo() serait également utile.

Je viens de trouver ce problème et c’était pour une raison simple. J’avais des étiquettes qui commençaient par un numéro et R ajoutait un X devant eux. Je pense que R est confondu avec un nombre dans l’en-tête et applique une lettre pour se différencier des valeurs.

Donc, “3_in” est devenu “X3_in” etc … J’ai résolu en changeant l’étiquette “in_3” et les problèmes ont été résolus.

J’espère que ça aidera quelqu’un.

J’ai rencontré un problème similaire et je voulais partager les lignes de code suivantes pour corriger les noms de colonne. Certainement pas parfait, car une programmation propre dans le coup droit serait meilleure, mais peut être utile comme sharepoint départ pour une approche rapide et sale. (J’aurais aimé les append en tant que commentaire à la question de Ryan / réponse de Gavin, mais ma réputation n’est pas assez élevée, alors j’ai dû poster une réponse supplémentaire – désolé).

Dans mon cas, plusieurs étapes d’écriture et de lecture des données ont produit une ou plusieurs colonnes nommées “X”, X.1 “, … contenant du contenu dans les colonnes X et les numéros de ligne des colonnes X.1, …-. Dans mon cas, le contenu de la colonne X doit être utilisé comme nom de ligne et les autres colonnes X.1, …- doivent être supprimées.

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

J’ai résolu un problème similaire en incluant row.names = FALSE comme argument dans la fonction write.csv. write.csv incluait les noms des lignes comme une colonne sans nom dans le fichier CSV et read.csv nommait cette colonne ‘X’ quand il lisait le fichier CSV.