在导入之前筛选CSV文件中的特定值

  • 本文关键字:文件 CSV 导入 筛选 r
  • 更新时间 :
  • 英文 :


我有一个文件夹,里面有数千个逗号分隔的CSV文件,总共有几十GB。每个文件都包含许多记录,我想根据第一个字段中的值(例如,aa、bb、cc等(对这些记录进行分离和单独处理

目前,我正在将所有文件导入到一个数据帧中,然后在R中细分为更小的单个数据帧。问题是这非常占用内存——我希望在导入过程中过滤第一列,而不是在所有数据都在内存中之后。

这是我当前的代码:

setwd("E:/Data/")
files <- list.files(path = "E:/Data/",pattern = "*.csv")
temp <- lapply(files, fread, sep=",", fill=TRUE, integer64="numeric",header=FALSE)
DF <- rbindlist(temp)
DFaa <- subset(DF, V1 =="aa")

如果可能的话,我想把";子集";加工成翻领。

感谢

1(read.csv.sql这将直接将文件读取到临时设置的SQLite数据库中(它为您执行此操作(,然后只将aa记录读取到R中。文件的其余部分在任何时候都不会读取到R。然后将从数据库中删除该表。

File是一个字符串,包含文件名(如果不在当前目录中,则为路径名(。根据数据的格式,可能需要其他参数。

library(sqldf)
read.csv.sql(File, "select * from file where V1 == 'aa'", dbname = tempfile())

2(grep/findstr另一种可能性是使用grep(Linux(或findstr(Windows(来提取带有aa的行。这应该会得到你想要的行,再加上可能的其他几行,在这一点上,你有一个小得多的输入,所以它可以在R中进行子集化,而不会出现内存问题。例如,

fread("findstr aa File")[V1 == 'aa'] # Windows
fread("grep aa File")[V1 == 'aa']    # Linux

sed或gawk也可以使用,并包含在Linux和Windows上的Rtools中。

3(外部csv实用程序这些外部实用程序理解csv,在R支持的所有平台上都是免费的:csvfix、csvkit、csvtk、miller和xsv(或xsv fork-qsv(。

我们展示了将fread与csvfix或xsv 一起使用的示例

# csvfix
fread("csvfix find -if $1==aa File")  # Windows
fread("csvfix find -if '$1'==aa File")  # Linux bash
# xsv (qsv has same syntax)
fread("xsv search aa --select 1 File.csv File")[V1 == "aa"]
setwd("E:/Data/")
files <- list.files(path = "E:/Data/",pattern = "*.csv")
temp <- lapply(files, function(x) subset(fread(x, sep=",", fill=TRUE, integer64="numeric",header=FALSE), V1=="aa"))
DF <- rbindlist(temp)

未测试,但这可能会起作用-用匿名函数替换您的函数调用。

这可能会有所帮助,但您必须扩展函数:

#Function
myload <- function(x) 
{
y <- fread(x, sep=",", fill=TRUE, integer64="numeric",header=FALSE)
y <- subset(y, V1 =="aa")
return(y)
}
#Apply
temp <- lapply(files, myload)

如果不想干扰SQL,可以考虑在循环中使用skip参数。速度较慢,但这样可以读取一块行,过滤它们,然后读取下一块行(到相同的临时变量,以免占用额外的内存(等。
lapply调用中,可以是第二个lapply或等效的

for (jj in 0: N) {
foo <-  fread(filename, skip = (jj*1000+1):((jj+1)*1000), sep=",", fill=TRUE, integer64="numeric",header=FALSE)
mydata[[jj]] <- do_something_to_filter(foo)
}

最新更新