在导入csv列的子集时,R中最有效的读取csv函数/包是什么

问题描述

我正在尝试将csv加载到R(即c)中。 180k行和c.9k列。我只需要一个c.100列的子集,并且知道我需要的列的名称

question的答案涵盖了导入CSV时用于选择列子集的许多不同选项。

使用这些答案和我自己的知识,我尝试使用read.csv中的read.tableutilsfread中的data.table和{{ 3}}来自read_csv。所有这些功能似乎都导入整个csv,然后将其子集作为子集-在我只需要一小部分子集的情况下,效率非常低。我还尝试过使用readr中的read.csv.sql,这似乎很有希望,因为选择特定的列是一项非常常见的sql任务,但是由于出现错误{{1},我无法导入列的子集}。

社区的两项贡献对我有很大帮助:

  1. 任何人都可以指向其他导入功能吗?如果我只需要列的子集,该功能会更加高效?
  2. 谁能提供有关这些功能如何工作的更多信息并纠正我的误解,或使我确信所寻找的解决方案不存在?

非常感谢!

P.S。之前我没有问过很多关于SO的问题,所以如果需要以其他方式提出问题,我将非常感谢您提供反馈。

解决方法

有许多命令行实用程序(例如sed,awk,cut,csvfix,miller,csvkit,csvtk)可以执行此操作。下面我们使用xsv。这将在文件到达R之前删除不需要的列。如果IoT上尚未包含iot,请使用xsv的完整路径。 xsv接受如下所示的列名或字段号。

# write out test data
write.csv(iris,"iris-test.csv",quote = FALSE,row.names = FALSE)

cmd <- "xsv select Sepal.Length,Petal.Length-Species iris-test.csv"
DF <- read.csv(pipe(cmd))

head(DF)
##   Sepal.Length Petal.Length Petal.Width Species
## 1          5.1          1.4         0.2  setosa
## 2          4.9          1.4         0.2  setosa
## 3          4.7          1.3         0.2  setosa
## 4          4.6          1.5         0.2  setosa
## 5          5.0          1.4         0.2  setosa
## 6          5.4          1.7         0.4  setosa

或与UNIX cut(在R 4.0+的\ Rtools40 \ usr \ bin中的Windows Rtools中也可用)一起使用,可以完成以下工作。如果cut上还没有cut,请使用完整路径PATH

cmd2 <- "cut -d,-f 1,3-5 iris-test.csv"
DF <- read.csv(pipe(cmd2))
,

这对我有用。与 csv 相比,我将 zstd 文件以 gzip 格式压缩以获得更好的性能。如果您使用 gzip 压缩的 csv 文件,只需将 zstd 替换为 gunzip 并调整命令行选项。

您需要在系统路径中保留从 https://github.com/facebook/zstd/releases 下载的 zstd 二进制文件和从 https://bioinf.shenwei.me/csvtk/ 下载的 csvtk 二进制文件。

假设您只需要加载三列,即。 YR_TA、MJH_CD、TV_TC_NO 从宽 csv 文件(其中还包含许多其他列)转换为 R,同时还指定所需列的数据类型。

以下代码仅将 csv 文件中的指定列加载到 R 中,R 甚至不知道 csv 文件中存在的其他列。

library(data.table)
fyl <- "... path to your compressed csv file"

# define column data type specification for R
cols <- c(YR_TA="factor",MJH_CD="character",TV_TC_NO="character")

dt <- fread(cmd = paste("zstd -dcq",fyl,"| csvtk cut -f YR_TA,MJH_CD,TV_TC_NO"),select = cols)

请注意,如果 csv 文件对于您的计算机 RAM 来说确实很大,使用 freadselect 语句中选择列将导致内存不足错误,因为 fread 仍然需要在选择之前在内存中映射整个 csv 文件。所以最好 fread 只看到所需的列。使用外部工具 fread 仅将所需的列流式传输到 csvtk 有助于实现这一点。