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

What is the most efficient read csv function / package in R at importing a subset of csv columns

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

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

根据这些答案和我自己的知识,我尝试使用 read.csv and read.table from utils, fread from data.table, and read_csv from readr. All of these functions seem to import the whole csv and then subset the columns - which is very inefficient where I only need such a small subset of columns. I have also tried to use read.csv.sql from sqldf,这似乎很有希望,因为选择特定列是一项非常常见的 SQL 任务,但我无法导入子集列因为我收到错误 Error: too many columns on file.

来自社区的两项真正帮助我的贡献:

  1. 任何人都可以指出一个不同的导入函数,它在我只需要一部分列的情况下效率更高吗?
  2. 任何人都可以提供有关这些功能如何工作的更多背景信息并纠正我的误解或向我保证我正在寻找的解决方案不存在吗?

非常感谢!

P.S。我之前没有问过很多关于 SO 的问题,所以如果我需要以不同的方式提问,我将不胜感激。

有许多命令行实用程序(例如 sed、awk、cut、csvfix、miller、csvkit、csvtk)可以执行此操作。下面我们使用xsv。这会在文件到达 R 之前删除不需要的列。如果 iot 不在 PATH 上,请使用 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

或在 R 4.0+ 中的 \Rtools40\usr\bin 中使用 UNIX cut (also available in Windows Rtools)以下工作。如果 cut 不在您的 PATH 上,请使用 cut 的完整路径。

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

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

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

假设您只需要加载三列,即。 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 来说确实很大,使用 selectfread 语句中选择列将导致内存不足错误,因为 fread在选择之前,仍然需要将 整个 csv 文件 映射到内存中。所以 fread 最好只看到必需的列。使用外部工具 csvtk 仅将所需的列流式传输到 fread 有助于实现这一点。