使用fread计算行而不读取整个文件

时间:2016-09-25 19:47:43

标签: r file size data.table row

我想使用data.table来处理一个非常大的文件。 它不适合记忆。 我已经考虑过使用循环读取块上的文件(正确增加跳过参数)。

fread("myfile.csv", skip=loopindex, nrows=chunksize) 

处理每个块并使用fwrite附加结果输出。

为了正确地做到这一点,我需要知道总行数,而不是读取整个文件。

正确/快速的方法是什么?

我只能在阅读第一栏时思考,但也许有一个特殊的命令或技巧。 或者可能有一种自动检测文件结尾的方法。

2 个答案:

答案 0 :(得分:4)

1)count.fields 不确定count.fields是否一次将整个文件读入R.试试它是否有效。

length(count.fields("myfile.csv", sep = ","))

如果文件有一个标题从上面减去一个。

2)sqldf 另一种可能性是:

library(sqldf)
read.csv.sql("myfile.csv", sep = ",", sql = "select count(*) from file")

您可能还需要其他参数,具体取决于标题等。请注意,这根本不会将文件读入R中 - 只能读入sqlite。

3)wc 使用系统命令wc,该命令应在R运行的所有平台上可用。

shell("wc -l myfile.csv", intern = TRUE)

或直接获取文件中的行数

read.table(pipe("wc -l myfile.csv"))[[1]]

read.table(text = shell("wc -l myfile.csv", intern = TRUE))[[1]]

同样,如果有一个标题减去一个。

如果您使用的是Windows,请确保已安装Rtools并使用此功能:

read.table(pipe("C:\\Rtools\\bin\\wc -l myfile.csv"))[[1]]

或者在没有Rtools的Windows上试试这个:

read.table(pipe('find /v /c "" myfile.csv'))[[3]]

请参阅How to count no of lines in text file and store the value into a variable using batch script?

答案 1 :(得分:2)

answer by @G. Grothendieck about using wc -l是一个很好的,如果你可以依赖它存在。

您可能还希望考虑以块的形式迭代文件,例如:通过使用仅依赖于基本R函数的like this answer

由于您不需要阅读单个行,因此您可以从连接中批量读取。例如:

count_lines = function(filepath, batch) {
    con = file(filepath, "r")
    n = 0
    while ( TRUE ) {
        lines = readLines(con, n = batch)
        present = length(lines)
        n = n + present
        if ( present <  batch) {
            break
        }
    }
    close(con)
    return(n)
}

然后你可以读取文件,例如每次1000行:

count_lines("filename.txt", 1000)