Прав ли я, предполагая, что это было бы невозможно со сжатым файлом просто потому, что gzip требует распаковать все с самого начала?
Действительно, для краткого объяснения возьмем за отправную точку какой-нибудь фиктивный метод:
AAAAVVBABBBC
gzip сделает что-то вроде: 4A2VBA3BC
Очевидно, что вы не можете извлечь все A
из файла, не прочитав его целиком, так как вы не можете угадать, есть ли в конце A
или нет.
На другой вопрос «Загрузка части сохраненного файла» я не вижу решения в своей голове. Вы, вероятно, можете с write.csv
и read.csv
(или fwrite
и fread
из пакета data.table
) с параметрами skip
и nrows
могли бы быть альтернативой.
Во что бы то ни стало, использование любой функции для уже прочитанного файла будет означать загрузку всего файла в память перед фильтрацией, что занимает не больше времени, чем чтение файла и последующее подмножество из памяти.
Вы можете создать что-то в Rcpp, используя потоки для чтения данных без загрузки их в память, но чтение и анализ каждой записи перед принятием решения о том, следует ли ее сохранить или нет, не даст вам действительно лучшей пропускной способности.
saveDRS
сохранит сериализованную версию данных, например:
> myvector <- c("1","2","3").
> serialize(myvector,NULL)
[1] 58 0a 00 00 00 02 00 03 02 03 00 02 03 00 00 00 00 10 00 00 00 03 00 04 00 09 00 00 00 01 31 00 04 00 09 00 00 00 01 32 00 04 00 09 00 00
[47] 00 01 33
Это, конечно, разборчиво, но означает чтение байт за байтом в соответствии с форматом.
С другой стороны, вы можете написать как csv (или write.table
для более сложных данных) и использовать внешний инструмент перед чтением, что-то вроде:
z <- tempfile()
write.table(df, z, row.names = FALSE)
shortdf <- read.table(text= system( command = paste0( "awk 'NR > 5 && NR < 10 { print }'" ,z) ) )
Вам понадобится система Linux с awk, который способный анализировать миллионы строк за несколько миллисекунд или использовать скомпилированную версию awk очевидно.
Основное преимущество заключается в том, что awk может фильтровать регулярное выражение или некоторые другие условия для каждой строки данных.
Дополнение для случая data.frame, data.frame - это более или менее список векторов (простой случай), этот список будет сохранен последовательно, поэтому, если у нас есть кадр данных, например:
> str(ex)
'data.frame': 3 obs. of 2 variables:
$ a: chr "one" "five" "Whatever"
$ b: num 1 2 3
Это сериализация:
> serialize(ex,NULL)
[1] 58 0a 00 00 00 02 00 03 02 03 00 02 03 00 00 00 03 13 00 00 00 02 00 00 00 10 00 00 00 03 00 04 00 09 00 00 00 03 6f 6e 65 00 04 00 09 00
[47] 00 00 04 66 69 76 65 00 04 00 09 00 00 00 08 57 68 61 74 65 76 65 72 00 00 00 0e 00 00 00 03 3f f0 00 00 00 00 00 00 40 00 00 00 00 00 00
[93] 00 40 08 00 00 00 00 00 00 00 00 04 02 00 00 00 01 00 04 00 09 00 00 00 05 6e 61 6d 65 73 00 00 00 10 00 00 00 02 00 04 00 09 00 00 00 01
[139] 61 00 04 00 09 00 00 00 01 62 00 00 04 02 00 00 00 01 00 04 00 09 00 00 00 09 72 6f 77 2e 6e 61 6d 65 73 00 00 00 0d 00 00 00 02 80 00 00
[185] 00 ff ff ff fd 00 00 04 02 00 00 00 01 00 04 00 09 00 00 00 05 63 6c 61 73 73 00 00 00 10 00 00 00 01 00 04 00 09 00 00 00 0a 64 61 74 61
[231] 2e 66 72 61 6d 65 00 00 00 fe
Перевел на ascii для идеи:
X
one five Whatever?ð@@ names a b row.names
ÿÿÿý class
data.frameþ
У нас есть заголовок файла, заголовок списка, затем каждый вектор, составляющий список, поскольку мы понятия не имеем, какой размер займет вектор символов, мы не можем переходить к произвольным данным, мы должны анализировать каждый заголовок (байты непосредственно перед текстовыми данными дают его длину). Что еще хуже, теперь, чтобы получить соответствующие целые числа, мы должны перейти к заголовку целочисленного вектора, который не может быть определен без анализа заголовка каждого символа и их суммирования.
Так что, на мой взгляд, создание чего-то возможно, но, вероятно, это будет не намного быстрее, чем чтение всего объекта, и будет хрупким для формата сохранения (поскольку в R уже есть 3 формата для сохранения объектов).
Некоторые ссылки здесь
Тот же вид, что и вывод сериализации в формате ascii (более читаемый, чтобы понять, как он организован):
> write(rawToChar(serialize(ex,NULL,ascii=TRUE)),"")
A
2
197123
131840
787
2
16
3
262153
3
one
262153
4
five
262153
8
Whatever
14
3
1
2
3
1026
1
262153
5
names
16
2
262153
1
a
262153
1
b
1026
1
262153
9
row.names
13
2
NA
-3
1026
1
262153
5
class
16
1
262153
10
data.frame
254
person
Tensibai
schedule
15.07.2016