我有一个data. frame,其中的字符列包含数字(如“0123”、“1234”等)。当我将它们写入csv并读回时,它们最终变成了数字列。write.csv
和read.csv
函数有quote
参数,默认情况下,在输出时应该用引号括起字符串,在输入时则遵守它们,因此这种行为是意外的。
如何避免这种情况,而不在重新读入文件时手动指定colClasses
?
可重现示例:
# dummy data
fake_data <-
data.frame(num=1:25, char=letters[1:25], charnum=as.character(1:25),
stringsAsFactors=F)
# check out col classes - all good
sapply(fake_data, class)
# num char charnum
# "integer" "character" "character"
# write it to a file and read it back
fpath <- '~/Desktop/fake_data.csv'
write.csv(fake_data, fpath, row.names=F)
fake_data2 <- read.csv(fpath, stringsAsFactors=F)
# but now look, different classes!
sapply(fake_data2, class)
# num char charnum
# "integer" "character" "integer"
错误似乎在读取端,因为文件是用引号写入的。
> cat(readLines(fpath))
"num","char","charnum" 1,"a","1" 2,"b","2" 3,"c","3" 4,"d","4" 5,"e","5" 6,"f","6" 7,"g","7" 8,"h","8" 9,"i","9" 10,"j","10" 11,"k","11" 12,"l","12" 13,"m","13" 14,"n","14" 15,"o","15" 16,"p","16" 17,"q","17" 18,"r","18" 19,"s","19" 20,"t","20" 21,"u","21" 22,"v","22" 23,"w","23" 24,"x","24" 25,"y","25"
会话信息:
R版本3.1.1(2014年7月10日)|平台:x86_64-苹果达尔文13.1.0(64位)
5条答案
按热度按时间cuxqih211#
谢谢你的回答。进一步来看,我有以下补充。
选项1:只使用数据。table::fread --按我希望的方式工作
选项2:执行此操作以构造colClasses字符串
因为我是data.table的粉丝,所以#1可能是我要做的。
yhqotfr82#
添加
quote=""
似乎可以实现您所期望的效果:bvn4nwqk3#
您可以使用quote参数来控制read.csv如何处理引号。如果您设置quote="”,则可以在R:
请注意,第二步需要使用引号剥离函数,因为fake_data2中的字符变量实际上包含引号。
jaql4c8m4#
这里的讨论很棒,但是对于那些只想把数字作为字符来保存并且需要快速回答的人(比如我)来说,可能会感到困惑。抱歉,我没有注意到问题中的前提条件“没有手动指定
colClasses
“。但是谷歌也没有,因为这个页面在谷歌搜索的顶部,我不敢相信我花了这么多时间才弄清楚。正确答案在前面答案的备注部分:
read.csv
选项中的“除了明确指定colClasses
,没有其他方法“。这也是将数字作为字符(或因子)获取的最简单方法。它与write.csv、stringsAsFactors或引号无关。而这个问题详细讨论了colClasses
:Specifying colClasses in the read.csv。另一个简单的方法是把原来的数字稍微修改一下,比如把0001修改成_0001。在我的情况下,这样也可以保存麻烦。
dfddblmv5#
使用data.table进行读写对我来说不起作用。
Write.csv()或data.table::fwrite()将看起来像数字的字符串写为数字。例如,当使用write.csv()或data.table::fwrite()写入字符串“001234”,然后在r中使用read.csv()或data.table::fread()读取该文件(或在Excel中作为csv)时,前一个字符串现在读作“1234”,并且具有类numeric。使用R的原生格式.Rds,保留变量类。等效命令是saveRDS()和readRDS()。希望这对其他人有所帮助。