Привязка data.frames для R по строкам без создания копий
У меня есть большой список data.frames, которые должны быть попарно связаны столбцами, а затем строками, прежде чем вводить их в прогнозную модель. Поскольку никакие значения не будут изменены, я хотел бы, чтобы окончательный data.frame указывал на исходные data.frames в моем списке.
Например:
library(pryr)
#individual dataframes
df1 <- data.frame(a=1:1e6+0, b=1:1e6+1)
df2 <- data.frame(a=1:1e6+2, b=1:1e6+3)
df3 <- data.frame(a=1:1e6+4, b=1:1e6+5)
#each occupy 16MB
object_size(df1) # 16 MB
object_size(df2) # 16 MB
object_size(df3) # 16 MB
object_size(df1, df2, df3) # 48 MB
#will be in a named list
dfs <- list(df1=df1, df2=df2, df3=df3)
#putting into list doesn't create a copy
object_size(df1, df2, df3, dfs) #48MB
Конечный data.frame будет иметь такую ориентацию (каждая уникальная пара data.frames связана столбцами, а затем парами, связанными строками):
df1, df2
df1, df3
df2, df3
В настоящее время я реализую это как так:
#generate unique df combinations
df_names <- names(dfs)
pairs <- combn(df_names, 2, simplify=FALSE)
#bind dfs by columns
combo_dfs <- lapply(pairs, function(x) cbind(dfs[[x[1]]], dfs[[x[2]]]))
#no copies created yet
object_size(dfs, combo_dfs) # 48MB
#bind dfs by rows
combo_df <- do.call(rbind, combo_dfs)
#now data gets copied
object_size(combo_df) # 96 MB
object_size(dfs, combo_df) # 144 MB
Как я могу избежать копирования своих данных, но при этом достичь того же конечного результата?
1 ответ
Сохранение значений, как вы надеетесь, потребует от R некоторого сжатия фрейма данных. Я не верю, что фреймы данных поддерживают сжатие.
Если вы не хотите помещать данные в память из-за того, что вы хотите сохранить данные таким образом, вы можете попробовать пакет ff. Это позволит вам более компактно хранить его на диске. Кажется, у класса ffdf есть нужные вам свойства:
По умолчанию создание объекта 'ffdf' НЕ будет создавать новые файлы ff, вместо этого будут ссылаться на существующие файлы. Это отличается от data.frame, который всегда создает копии входных объектов, особенно в data.frame(matrix()), где входная матрица преобразуется в отдельные столбцы. ffdf, напротив, физически сохранит входную матрицу как ту же матрицу и виртуально отобразит ее в столбцы.
Кроме того, пакет ff оптимизирован для быстрого доступа.
Обратите внимание, что я сам не использовал этот пакет, поэтому не могу гарантировать, что он решит вашу проблему.