使用 data.table::fread 读取特定的非连续行(相当于“Select”参数,但对于行)?
Read specific, non-consecutive rows using data.table::fread (equivalent to the “Select” argument, but for rows)?
fread 函数 (data.table) 使用户能够使用 'select' 参数定义要读入的数据帧的特定列(例如 fread(input, select=c(1, 5,10))。我想要相同的能力,但对于行(例如 fread(input,selectrows=c(1,4,47)))。我 could 在读取文件后执行此操作,但这需要很长时间,我希望通过只读取我需要的行来优化流程。
我知道有许多选项可以根据 'within-file' 条件以编程方式 selecting 行:
Read csv file with selected rows using data.table's fread
Quickest way to read a subset of rows of a CSV
...但我希望能够使用根据要读入的给定文件之外的条件定义的矢量(如此 question,但特别是使用 fread)。
一种方法(虽然有点brute-force)是用sed
剪线
回想一下 fread
需要 file=
以及 cmd=
,如
library(data.table)
fwrite(iris, "iris.csv")
fread(cmd = "head -n 3 iris.csv")
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1: 5.1 3.5 1.4 0.2 setosa
# 2: 4.9 3.0 1.4 0.2 setosa
(两行,因为 head
没有 know/care 关于 header 行。)
试试这个:
want_rows <- c(1, 3, 147:149)
# due to the header row, add the header and 1 to each of want
paste0(c(1, 1+want_rows), "p")
# [1] "1p" "2p" "4p" "148p" "149p" "150p"
writeLines(paste0(c(1, 1+want_rows), "p"), "commands.sed")
fread(cmd = "sed -n -f commands.sed iris.csv")
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1: 5.1 3.5 1.4 0.2 setosa
# 2: 4.7 3.2 1.3 0.2 setosa
# 3: 6.3 2.5 5.0 1.9 virginica
# 4: 6.5 3.0 5.2 2.0 virginica
# 5: 6.2 3.4 5.4 2.3 virginica
iris[want_rows,]
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 5.1 3.5 1.4 0.2 setosa
# 3 4.7 3.2 1.3 0.2 setosa
# 147 6.3 2.5 5.0 1.9 virginica
# 148 6.5 3.0 5.2 2.0 virginica
# 149 6.2 3.4 5.4 2.3 virginica
如果您有重要的 "ranges",那么您可以针对 sed
稍微优化一下,以获得相同效果的有效命令行 sed -ne '1p;2p;4p;148,150p'
。
此处列出了另一种方法 "every so many rows":https://www.thegeekstuff.com/2009/09/unix-sed-tutorial-printing-file-lines-using-address-and-patterns/。我不知道你能控制得有多严密(例如,从某个任意数字开始的每 n 行)。我不知道这是你的意图或需要,但听起来会有任意行号。
fread 函数 (data.table) 使用户能够使用 'select' 参数定义要读入的数据帧的特定列(例如 fread(input, select=c(1, 5,10))。我想要相同的能力,但对于行(例如 fread(input,selectrows=c(1,4,47)))。我 could 在读取文件后执行此操作,但这需要很长时间,我希望通过只读取我需要的行来优化流程。
我知道有许多选项可以根据 'within-file' 条件以编程方式 selecting 行:
Read csv file with selected rows using data.table's fread
Quickest way to read a subset of rows of a CSV
...但我希望能够使用根据要读入的给定文件之外的条件定义的矢量(如此 question,但特别是使用 fread)。
一种方法(虽然有点brute-force)是用sed
剪线
回想一下 fread
需要 file=
以及 cmd=
,如
library(data.table)
fwrite(iris, "iris.csv")
fread(cmd = "head -n 3 iris.csv")
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1: 5.1 3.5 1.4 0.2 setosa
# 2: 4.9 3.0 1.4 0.2 setosa
(两行,因为 head
没有 know/care 关于 header 行。)
试试这个:
want_rows <- c(1, 3, 147:149)
# due to the header row, add the header and 1 to each of want
paste0(c(1, 1+want_rows), "p")
# [1] "1p" "2p" "4p" "148p" "149p" "150p"
writeLines(paste0(c(1, 1+want_rows), "p"), "commands.sed")
fread(cmd = "sed -n -f commands.sed iris.csv")
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1: 5.1 3.5 1.4 0.2 setosa
# 2: 4.7 3.2 1.3 0.2 setosa
# 3: 6.3 2.5 5.0 1.9 virginica
# 4: 6.5 3.0 5.2 2.0 virginica
# 5: 6.2 3.4 5.4 2.3 virginica
iris[want_rows,]
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 5.1 3.5 1.4 0.2 setosa
# 3 4.7 3.2 1.3 0.2 setosa
# 147 6.3 2.5 5.0 1.9 virginica
# 148 6.5 3.0 5.2 2.0 virginica
# 149 6.2 3.4 5.4 2.3 virginica
如果您有重要的 "ranges",那么您可以针对 sed
稍微优化一下,以获得相同效果的有效命令行 sed -ne '1p;2p;4p;148,150p'
。
此处列出了另一种方法 "every so many rows":https://www.thegeekstuff.com/2009/09/unix-sed-tutorial-printing-file-lines-using-address-and-patterns/。我不知道你能控制得有多严密(例如,从某个任意数字开始的每 n 行)。我不知道这是你的意图或需要,但听起来会有任意行号。