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

ymzxtsji  于 2023-01-22  发布在  其他
关注(0)|答案(2)|浏览(113)

我试图将一个csv文件加载到R中,它有c.180k行和c.9k列,我只需要c.100列的一个子集,并且知道我需要的列的名称。
这个question的答案涵盖了导入csv时选择列子集的许多不同选项。
利用这些答案和我自己的知识,我尝试从utils使用read.csvread.table,从data.table使用fread,所有这些函数似乎都导入了整个csv,然后对列进行子集化--在我只需要这么小的一个列子集的情况下,这是非常低效的。我还尝试过从sqldf使用read.csv.sql,这看起来很有前途,因为选择特定列是一项非常常见的SQL任务,但我无法导入列的子集,因为我得到了错误Error: too many columns on file
来自社区的两个贡献会真正帮助我:
1.有人能指出一个不同的导入函数吗?在我只需要一个列子集的情况下,这个函数会更有效。
1.有谁能提供更多关于这些功能如何工作的背景信息,纠正我的误解,或者让我放心,我正在寻找的解决方案并不存在?
非常感谢!
另外,我以前没有问过很多关于SO的问题,所以如果我需要用不同的方式问的话,我会很感激你的反馈。

a1o7rhls

a1o7rhls1#

有许多命令行工具可以做到这一点(例如sed、awk、cut、csvfix、米勒、csvkit、csvtk)。下面我们使用xsvreleases)。这将在文件到达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

或者,对于UNIX cut(也可在Windows Rtools中的\Rtools40\usr\bin中找到R 4.0+),可以使用以下方法。如果cut不在PATH上,请使用cut的完整路径。

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

wwwo4jvm2#

我是这样做的:我把csv文件压缩成zstd,这样比gzip的性能更好。如果你使用gzip格式的csv文件,只需把zstd替换成gunzip,并调整命令行选项。
您需要将从https://github.com/facebook/zstd/releases下载的zstd二进制文件和从https://bioinf.shenwei.me/csvtk/下载的csvtk二进制文件保存在系统路径中。
假设您只需要从一个宽csv文件(还包含许多其他列)中加载三列,即YR_TA、MJH_CD、TV_TC_NO到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文件Map到内存中。因此,fread最好只查看所需的列。使用外部工具csvtk仅将所需列流式传输到fread有助于实现这一点。

相关问题