为什么我在读取数据框时会在列名中获得X.

时间:2012-05-04 01:11:51

标签: r dataframe read.csv illegal-characters

我问了一个question about this a few months back,我认为答案已经解决了我的问题,但我又遇到了问题,解决方案对我不起作用。

我正在导入CSV:

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

这是数据帧的结构:

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

如果我在第一列OrderID上运行length命令,我会得到:

length(orders$OrderID)
[1] 0

如果我在OrderDate上运行length,它会正确返回:

length(orders$OrderDate)
[1] 3331575

这是head 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

现在,如果我重新运行read.csv,但取出check.names选项,则dataframe的第一列现在在名称的开头有一个X.

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

这可以正常工作。

我的问题是R为什么在第一个列名的开头添加X.?从CSV文件中可以看出,没有特殊字符。它应该是一个简单的负载。添加check.names,同时将从CSV导入名称,将导致数据无法正确加载,以便我执行分析。

我该怎么做才能解决这个问题?

旁注:我意识到这是次要的 - 我更加沮丧的是,我认为我正确加载,但没有得到我预期的结果。我可以使用colnames(orders)[1] <- "OrderID"重命名列,但仍想知道为什么它没有正确加载。

5 个答案:

答案 0 :(得分:66)

read.csv()是更通用的read.table()函数的包装器。后一个函数的参数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.

如果您的标头包含在语法上无效的标签,那么make.names()将使用有效名称替换它们,基于无效名称,删除无效字符并可能在X之前添加:

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

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

您看到的行为与数据中记录的read.table()加载方式完全一致。这表明您在CSV文件的标题行中有语法上无效的标签。请注意?make.names上面的内容,即字母是什么取决于系统的区域设置; CSV文件可能包含文本编辑器将显示的有效字符,但如果R没有在相同的区域设置中运行,那么该字符可能无效,例如?

我会查看CSV文件并识别标题行中的任何非ASCII字符;标题行中可能还有不可见的字符(或转义序列; \t?)。在使用无效名称读取文件并在控制台中显示它可能会掩盖无效字符之间可能会发生很多事情,因此如果没有{没有显示任何错误,请不要这样做。 {1}}表示文件正常。

发布check.names的输出也很有用。

答案 1 :(得分:10)

我刚刚遇到这个问题,原因很简单。我的标签以数字开头,R在它们前面添加了一个X.我认为R与标题中的数字混淆并应用字母来区分值。

所以,&#34; 3_in&#34;成了&#34; X3_in&#34;等等... 我通过将标签切换到&#34; in_3&#34;问题得到了解决。

我希望这有助于某人。

答案 2 :(得分:7)

我遇到了类似的问题,想要共享以下代码行来更正列名。当然不是完美的,因为正手的清洁编程会更好,但可能有助于作为快速和肮脏方法的人的起点。 (我本来希望将它们添加为对Ryan的问题/ Gavin的答案的评论,但我的声誉不够高,所以我不得不发一个额外的答案 - 抱歉)。

在我的例子中,编写和读取数据的几个步骤产生了一个或多个名为&#34; X&#34;,X.1&#34;,...的列,其中包含X列中的内容和行中的行号。 X.1,...-列。在我的例子中,X列的内容应该用作行名,而其他X.1,...-列应该被删除。

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

答案 3 :(得分:2)

我通过在write.csv函数中包含row.names = FALSE作为参数来解决类似的问题。 write.csv包含行名称作为CSV文件中的未命名列,read.csv在读取CSV文件时将该列命名为“X”。

答案 4 :(得分:1)

当列名的格式不正确时,R在导入过程中在列名的开头添加一个“ X”。例如,当您的列名以数字或某些空格字符开头时,通常会发生这种情况。 var a = pm.cookies.get('session'); pm.globals.set("session", a); 的原因将不会发生-不会出现“ X”。 但是,如果列名以数字或其他特殊字符开头,则某些功能可能不起作用。示例是check.names = FALSE函数。

因此,在应用了该函数(带有“更正的colnames”后)之后,我使用了这个简单的方法来摆脱“ X”。

rbind.fill