Прочитать спецификацию c, непоследовательные строки, используя data.table :: fread (эквивалентно аргументу «Выбрать», но для строк)? - PullRequest
1 голос
/ 21 апреля 2020

Функция fread (data.table) позволяет пользователям определять определенные c столбцы данных для чтения, используя аргумент 'select' (например, fread (input, select = c (1,5,10)) Я хотел бы такую ​​же возможность, но для строк (например, fread (input, selectrows = c (1,4,47)). Я мог бы сделать это после чтения в файлах, но это требует очень долгое время, и я надеюсь оптимизировать процесс, читая только те строки, которые мне нужны.

Мне известен ряд вариантов программного выбора строк на основе критериев «в файле»:

Чтение файла CSV с выбранными строками с использованием файла data.table

Самый быстрый способ чтения подмножества строк CSV

. ... но я хочу иметь возможность использовать вектор, определенный на основе критериев вне данного файла, для чтения (как в этом вопросе , но специально с использованием fread).

1 Ответ

1 голос
/ 21 апреля 2020

Один метод (хотя и с небольшим перебором) заключается в использовании 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 не знает / не заботится о строке заголовка.)

Попробуйте:

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

Если у вас есть значительные "диапазоны ", тогда вы могли бы немного оптимизировать это для sed, чтобы эффективная командная строка равнялась sed -ne '1p;2p;4p;148,150p' для того же эффекта.

Существует другой метод ala" каждые так много строк ", перечисленный здесь: https://www.thegeekstuff.com/2009/09/unix-sed-tutorial-printing-file-lines-using-address-and-patterns/. Я не знаю, насколько сильно вы можете контролировать это (например, каждая n -я строка, начиная с некоторого произвольного числа). Я не знаю, что это ваше намерение или необходимость, хотя, похоже, будет иметь произвольные номера строк.

...