2014-04-04 88 views
1

我试图使用ff包将大型(370万行,180列)数据集读入R中。数据集中有几种数据类型 - 因子,逻辑和数字。使用read.csv.ffdf()会抛出一个错误

问题是在读数值变量时。例如,我的专栏之一是:

TotalBeforeTax 
126.9 
88.0 
124.5 
90.9 
... 

当我尝试在读取数据时,被抛出了以下错误:

Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings, : 
    scan() expected 'a real', got '"126.90000"' 

我想声明的类integer(它已经被声明为numeric )使用colClasses的说法,但无济于事。我也试着将其更改为a real(不管是应该的意思),并开始读取数据,但在某些时候抛出:

Error in methods::as(data[[i]], colClasses[i]) : 
    no method or default for coercing “character” to “a real” 

(我的猜测是,因为它遇到一个NA并没有按我不知道该怎么处理它。)

有趣的是,如果我将该列声明为factor,则所有内容都会很好地读取。

什么给?

+0

另请参见http://stackoverflow.com/questions/22357396/ff-in-r-no-applicable-method-for-recodelevels – jwijffels

回答

2

好的,所以我设法解决这个使用原始的解决方法。首先,使用csv文件分割器应用程序分割.csv文件。然后,执行以下代码:

## First, set the folder where the split .csv files are. Set the file names. 

sourceDir <- "split_files_folder" 
sourceFile <- paste(sourceDir,"common_name_of_split_files", sep = "/") 

## Now set the number of split pieces. 

pieces <- "some_number" 

## Set the destination folder for the tab-delimited text files. 
## Set the output file name. 

destDir <- "destination_folder" 
destFile <- paste(paste(destDir, "datafile", sep = "/"), "txt", sep = ".") 

## Now, initialize the loop. 

for (i in 1:pieces) 
{ 
    temp <- read.csv(file = paste(paste(sourceFile, i, sep = "_"), "csv", sep = ".")) 
    if (i == 1) 
    { 
    write.table(temp, file = destFile, quote = FALSE, sep = "\t", row.names = FALSE, col.names = TRUE) 
    } 
    else 
    { 
    write.table(temp, file = destFile, append = TRUE, quote = FALSE, sep = "\t", row.names = FALSE, col.names = FALSE) 
    } 
} 

瞧!你有一个巨大的制表符分隔的文本文件!

+0

感谢您的回答,@neuron。为了提高循环的速度,我建议使用data.table包中的fread()而不是read.csv。函数fread可能是读取数据集的最快方法,如这些基准https://rpubs.com/dpastoor/benchmark-nmread和 –

0

这个问题似乎是数126.9000通过报价”所包围。 因此,也许你应该先得到变量字符;其次去掉所有不需要的字符,最后的变量转换为数值。

+0

我认为,以及当我使用普通的'read.csv'函数读入,例如,前几千行,它的作用就像一个魅力。另外,我不确定我是否可以按照常规方式更改“ff”数据框中的列类型。 – neuron

+0

@ssantic前段时间在r-devel列表上有关于这个问题的讨论:https://stat.ethz.ch/pipermail/r-devel/2013-September/067605.html。并不是说有一个解决方案在那里... –

1

方案1

你可以从ffbase尝试软件包laf_to_ffdf喜欢的东西:

library(LaF) 
library(ffbase) 

con <- laf_open_csv("yourcsvfile.csv", 
    column_names = [as character vector with column names], 
    column_types = [a character vector with colClasses], 
    dec=".", sep=",", skip=1) 

ffdf <- laf_to_ffdf(con) 

或者,如果要自动检测类型:

library(LaF) 
library(ffbase) 

m <- detect_dm_csv("yourcsvfile.csv") 
con <- laf_open(m) 
ffdf <- laf_to_ffdf(con) 

解决方案2

使用列类character对于违规列和transFUN说法read.csv.ffdf铸列数字:

ffdf <- read.csv.ffdf([your regular arguments], transFUN = function(d) { 
    d$offendingcolumn <- as.numeric(d$offendingcolumn) 
    d 
}) 
+0

我试过解决方案2.不幸的是,阅读功能不支持字符(你可以检查'.vimplemented'),并引发错误。我尝试将它们加载为因子,并用'transFUN'将它们转换为数字,但这给出了错误的值。 – neuron

+0

所以,我设法解决它使用原始的解决方法。我使用了一个csv分离器应用程序将文件分解为每个50,000行可管理的块。然后,我编写了一个R脚本来加载一个块,然后将其导出为制表符分隔的文本文件,然后加载下一个块,将其导出并将输出附加到已生成的文本文件中,依此类推。加载数值或整数值时,'read.delim.ffdf'函数不会引起任何问题。 – neuron

+0

@ssantic太糟糕了,第二个解决方案无法正常工作。这可能与'read.csv.ffdf'在colClasses更改时不喜欢它有关。第一个(可能的)解决方案? –

相关问题