问题描述
我正在尝试将csv加载到R(即c)中。 180k行和c.9k列。我只需要一个c.100列的子集,并且知道我需要的列的名称。
此question的答案涵盖了导入CSV时用于选择列子集的许多不同选项。
使用这些答案和我自己的知识,我尝试使用read.csv中的read.table和utils,fread中的data.table和{{ 3}}来自read_csv。所有这些功能似乎都导入整个csv,然后将其子集作为子集-在我只需要一小部分子集的情况下,效率非常低。我还尝试过使用readr中的read.csv.sql,这似乎很有希望,因为选择特定的列是一项非常常见的sql任务,但是由于出现错误{{1},我无法导入列的子集}。
社区的两项贡献对我有很大帮助:
非常感谢!
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 来说确实很大,使用 fread
从 select
语句中选择列将导致内存不足错误,因为 fread
仍然需要在选择之前在内存中映射整个 csv
文件。所以最好 fread
只看到所需的列。使用外部工具 fread
仅将所需的列流式传输到 csvtk
有助于实现这一点。