read.csv和fread为同一数据帧产生不同的结果

read.csv和fread为同一数据帧产生不同的结果

问题描述:

fread函数from data.table包读取大于csv文件大于read.cvs函数。但是从两个例程的数据帧的输出中可以看到,对于“device _id”列(请参见最后3位数字)不同。为什么?这些函数中是否有参数可以正确读取它们?或者这是fread的正常行为? (尽管它读取的数据文件速度提高了10倍)。read.csv和fread为同一数据帧产生不同的结果

# Read file 
p<-fread("C:\\User\\Documents\\Data\\device.csv",sep=", integer64="character") 
> str(p) 
     Classes ‘data.table’ and 'data.frame': 187245 obs. of 3 variables: 
     $ device_id : Factor w/ 186716 levels "-1000025442746372936",..: 89025 96789 140102 123523 45208 118633 32423 22215 54410 81947 ... 
     $ phone_brand : Factor w/ 131 levels "E<U+4EBA>E<U+672C>""| __truncated__,"E<U+6D3E>""| __truncated__,..: 52 52 16 10 16 32 52 32 52 14 ... 
     $ device_model: Factor w/ 1598 levels "1100","1105",..: 1517 750 561 1503 537 775 753 433 759 983 ... 
     - attr(*, ".internal.selfref")=<externalptr> 

> head(p) 
          device_id   brand      device_model 
      1: -8890648629457979026 <U+5C0F><U+7C73>     <U+7EA2><U+7C73> 
      2: 1277779817574759137 <U+5C0F><U+7C73>        MI 2 
      3: 5137427614288105724 <U+4E09><U+661F>      Galaxy S4 
      4: 3669464369358936369   SUGAR <U+65F6><U+5C1A><U+624B><U+673A> 
      5: -5019277647504317457 <U+4E09><U+661F>     Galaxy Note 2 
      6: 3238009352149731868 <U+534E><U+4E3A>        Mate 

# Read file 
p<-read.csv("C:\\Users\\Documents\\Data\\device.csv",sep=",") 

# Convert device_id to character 
> p$device_id<-as.character(p$device_id) 

> str(p) 
    'data.frame': 187245 obs. of 3 variables: 
$ device_id : chr "-8890648629457979392" "1277779817574759168" "5137427614288105472" "3669464369358936576" ... 
$ phone_brand : chr "<U+5C0F><U+7C73>""| __truncated__ "<U+5C0F><U+7C73>""| __truncated__ "<U+4E09><U+661F>""| __truncated__ "SUGAR" ... 
$ device_model: chr "<U+7EA2><U+7C73>""| __truncated__ "MI 2" "Galaxy S4" "<U+65F6><U+5C1A><U+624B><U+673A>""| __truncated__ ... 

    > head(p) 
        device_id   brand      device_model 
     1 -8890648629457979392 <U+5C0F><U+7C73>     <U+7EA2><U+7C73> 
     2 1277779817574759168 <U+5C0F><U+7C73>        MI 2 
     3 5137427614288105472 <U+4E09><U+661F>      Galaxy S4 
     4 3669464369358936576   SUGAR <U+65F6><U+5C1A><U+624B><U+673A> 
     5 -5019277647504317440 <U+4E09><U+661F>     Galaxy Note 2 
     6 3238009352149731840 <U+534E><U+4E3A>        Mate 
+0

我谷歌的代码,它似乎是一些中国字符的unicodes。您是否尝试导入中国品牌和设备? – brettljausn

+1

尝试用'str()'或其他东西显示每个列的'class()'。文件中的实际值是什么?如果你提供了一个适当的[可重现的例子](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example),它会更容易帮助。在这两种情况下,您可能都希望强制device_id成为字符值。这可能是'read.csv'的数字。 – MrFlick

+0

正如@MrFlick所写,请提供文件以供审查。另外,如果你正在寻找速度和更好地控制编码,你应该试试'readr :: read_csv'。 –

如果bit64库目前,fread会自动使用它来正确读取超过2^32的整数 - 1

read.csv没有做到这一点,所以它从溢流受到影响。更快,更方便

类似read.table但:

这是第一款在?fread提及。自动检测到所有控件,如sep,colClassesnrowsbit64::integer64类型也可以在转换前直接检测和读取,而不需要读取字符。

您正在使用integer64="character"选项,因此它们将被检测并读取为字符。使用read.table时,它们不会被检测到,也不会被读为字符。如果要read.csv的行为类似,则需要使用colClasses参数指定在导入过程中要作为字符读取的列。当它被读入时,已经太晚了。溢出已经导致信息丢失,p$device_id<-as.character(p$device_id)不能“撤销”这个问题。

这些函数中是否有参数正确读取它们?或者这是fread的正常行为?

是的,fread正在读东西,这是正常行为。 read.csv需要更多的工作才能正确地读取内容 - 您需要使用colClassses参数将长整数作为字符读取。它仍然会变慢。

就像泰格优雅地讨论了read.csv函数在读取64位数字时有局限性。就像fread一样,如果参数numerals被定义为“no.loss”,read.cvs也可以。感谢这个问题的所有贡献者。

p<-read.csv("C:\\Users\\Documents\\Data\\device.csv",sep=",",encoding="UTF-8", numerals="no.loss") 

> head(p) 
       device_id  phone_brand      device_model 
1: -8890648629457979026 <U+5C0F><U+7C73>     <U+7EA2><U+7C73> 
2: 1277779817574759137 <U+5C0F><U+7C73>        MI 2 
3: 5137427614288105724 <U+4E09><U+661F>      Galaxy S4 
4: 3669464369358936369   SUGAR <U+65F6><U+5C1A><U+624B><U+673A> 
5: -5019277647504317457 <U+4E09><U+661F>     Galaxy Note 2 
6: 3238009352149731868 <U+534E><U+4E3A>        Mate