从 csv 读取特定(非连续)行

Posted

技术标签:

【中文标题】从 csv 读取特定(非连续)行【英文标题】:Read specific (non-consecutive) rows from csv 【发布时间】:2019-12-20 04:53:15 【问题描述】:

我有一个大的 csv 文件,并且只想读取某些行,这些行由要读取的行号向量定义。有没有办法在不将整个 csv 读入内存的情况下读取这些行?

我发现的唯一解决方案似乎允许读取连续行(例如第 2-100 行)。

【问题讨论】:

可以看看sqldfhelps:rdocumentation.org/packages/sqldf/versions/0.4-11/topics/… @JonnyPhelps 谢谢,我考虑过尝试,但是这些行不容易从 csv 中的数据中子集化,并且希望避免根据是否应选择行向电子表格添加列。 @joran 是的,命令行可能是要走的路,我只是认为 R 中可能有一种快速的方法。 可以使用skipnrows 的适当组合来读取单个行(或小块),然后将结果粘合在一起......但可能不会很好。 【参考方案1】:

一个简单的例子,说明如何将我链接到的 sed 方法组合到 R 函数中:

read_rows <- function(file,rows,...)
  tmp <- tempfile()
  row_cmd <- paste(paste(rows,"p",sep = ""),collapse = ";")
  cmd <- sprintf(paste0("sed -n '",row_cmd,"' %s > %s"),file,tmp)
  system(command = cmd)
  read.table(file = tmp,...)


write.csv(x = mtcars,file = "~/Desktop/scratch/mtcars.csv")

    > read_rows(file = "~/Desktop/scratch/mtcars.csv",rows = c(3,6,7),sep = ",",header = FALSE,row.names = 1)
                    V2 V3  V4  V5   V6    V7    V8 V9 V10 V11 V12
Mazda RX4 Wag     21.0  6 160 110 3.90 2.875 17.02  0   1   4   4
Hornet Sportabout 18.7  8 360 175 3.15 3.440 17.02  0   0   3   2
Valiant           18.1  6 225 105 2.76 3.460 20.22  1   0   3   1
> read_rows(file = "~/Desktop/scratch/mtcars.csv",rows = c(1,5,9),sep = ",",header = TRUE,row.names = 1)
                mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Merc 240D      24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2

注意与第 1 行作为列标题的区别。

【讨论】:

【参考方案2】:

sqldf 会将其读入数据库(它将为您创建然后删除),然后只将您想要的行读入 R。假设在最后的注释中创建的 csv 文件定义所需的 Rows 和然后使用read.csv.sql。我们为数据库使用了一个临时文件,但如果数据足够小,您可以省略 dbname 参数,它会占用内存。

library(sqldf)

Rows <- c(3, 5, 10)

s <- toString(Rows)
fn$read.csv.sql("Letters.csv", "select * from file where rowid in ($s)",
   dbname = tempfile())

给予:

     X Letters
1  "3"     "c"
2  "5"     "e"
3 "10"     "j"

如果所需的行数非常大,那么与其在 SQL 语句中嵌入行号,不如从它们创建一个数据框并加入它:

library(sqldf)

Rows <- c(3, 5, 10)
RowsDF <- data.frame(Rows)

s <- toString(Rows)
fn$read.csv.sql("Letters.csv", 
  "select file.* from file join RowsDF on file.rowid = RowsDF.Rows",
  dbname = tempfile())

注意

Letters <- data.frame(Letters = letters, stringsAsFactors = FALSE)
write.csv(Letters, "Letters.csv")

【讨论】:

以上是关于从 csv 读取特定(非连续)行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 fread 函数读取 CSV 文件的特定行

R-从 PurpleAir 传感器读取 csv 文件并跳过某些行末尾包含非标准字符的错误位置

如何从特定行号读取csv文件到提供的行号? [关闭]

是否可以使用 read_csv 仅读取特定行?

有没有办法读取 C++ 中连续特定行上的数字?

逐列读取 CSV 文件