mik*_*sey 55 r illegal-characters dataframe read.csv
几个月前我问了一个关于这个的问题,我认为答案已经解决了我的问题,但是我再次遇到了问题并且解决方案对我不起作用.
我正在导入CSV:
orders <- read.csv("<file_location>", sep=",", header=T, check.names = FALSE)
Run Code Online (Sandbox Code Playgroud)
这是数据帧的结构:
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 ...
Run Code Online (Sandbox Code Playgroud)
如果我length在第一列OrderID上运行命令,我会得到:
length(orders$OrderID)
[1] 0
Run Code Online (Sandbox Code Playgroud)
如果我运行length在OrderDate上,它会正确返回:
length(orders$OrderDate)
[1] 3331575
Run Code Online (Sandbox Code Playgroud)
这是复制/粘贴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
Run Code Online (Sandbox Code Playgroud)
现在,如果我重新运行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
Run Code Online (Sandbox Code Playgroud)
这工作正常.
我的问题是为什么R在第一列名称的开头添加X.?从CSV文件中可以看出,没有特殊字符.它应该是一个简单的负载.添加check.names虽然将从CSV导入名称,但会导致数据无法正确加载以供我执行分析.
我该怎么做才能解决这个问题?
旁注:我意识到这是次要的 - 我更加沮丧的是,我认为我正确加载,但没有得到我预期的结果.我可以使用重命名列colnames(orders)[1] <- "OrderID",但仍然想知道为什么它没有正确加载.
Rei*_*son 72
read.csv()是一个更通用的read.table()函数的包装器.后一个函数的参数check.names记录为:
Run Code Online (Sandbox Code Playgroud)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"
Run Code Online (Sandbox Code Playgroud)
这记录在?make.names:
Run Code Online (Sandbox Code Playgroud)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标题行中也可能存在不可见的字符(或转义序列; ?).很多可能读数之间与非有效名称的文件中去并在可能掩盖了非有效字符控制台显示出来,所以不要拿一个事实,即它并没有显示任何错误,而不check.names为表明文件正常.
发布输出sessionInfo()也很有用.
小智 10
我刚刚遇到这个问题,原因很简单.我的标签以数字开头,R在它们前面添加了一个X. 我认为R与标题中的数字混淆并应用字母来区分值.
所以,"3_in"变成了"X3_in"等...我通过将标签切换为"in_3"来解决问题并解决了问题.
我希望这可以帮助别人.
我遇到了类似的问题,并希望共享以下代码行来更正列名.当然不是完美的,因为正手的清洁编程会更好,但可能有助于作为快速和肮脏方法的人的起点.(我本来希望将它们添加为对Ryan的问题/ Gavin的答案的评论,但我的声誉不够高,所以我不得不发一个额外的答案 - 抱歉).
在我的例子中,编写和读取数据的几个步骤产生了一个或多个名为"X",X.1",......的列,其中包含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)
}
Run Code Online (Sandbox Code Playgroud)
小智 6
当列名的格式不正确时,R 在导入期间在列名的开头放置一个“X”。例如,当您的列名以数字或某些空格字符开头时,通常会发生这种情况。check.names = FALSE它不会发生的原因 - 不会有“X”。但是,如果列名称以数字或其他特殊字符开头,则某些功能可能不起作用。例子是rbind.fill函数。
因此,在应用该函数(使用“更正的列名”)之后,我使用这个简单的东西来摆脱“X”。
destroyX = function(es) {
f = es
for (col in c(1:ncol(f))){ #for each column in dataframe
if (startsWith(colnames(f)[col], "X") == TRUE) { #if starts with 'X' ..
colnames(f)[col] <- substr(colnames(f)[col], 2, 100) #get rid of it
}
}
assign(deparse(substitute(es)), f, inherits = TRUE) #assign corrected data to original name
}
Run Code Online (Sandbox Code Playgroud)
小智 5
row.names=FALSE我通过将参数包含在函数中解决了类似的问题write.csv。write.csv将行名称作为未命名列包含在 CSV 文件中,并read.csv在读取 CSV 文件时将该列命名为“X”。
| 归档时间: |
|
| 查看次数: |
71401 次 |
| 最近记录: |