是否有一种好的方法或算法来确定行和列的最佳排序和排列,以最小化磁盘上R data.frame的文件大小?
考虑以下数据:
# Init
library(dplyr)
set.seed(12345)
n_rows <- 10e6
df_1 <- data.frame(
V1 = sample(1:10, n_rows, replace=TRUE),
V2 = sample(1:2, n_rows, replace=TRUE),
V3 = sample(1:100, n_rows, replace=TRUE),
V4 = sample(1:1000, n_rows, replace=TRUE),
V5 = sample(1:5, n_rows, replace=TRUE)
) %>% as_data_frame()
df_2 <- df_1 %>% arrange(
V2, V5, V1, V3, V4
)
df_3 <- df_2 %>% select(
V2, V5, V1, V3, V4
)
saveRDS(df_1, "temp_1.RDS")
saveRDS(df_2, "temp_2.RDS")
saveRDS(df_3, "temp_3.RDS")
输出文件大小为:
在这个设置中,我们通过以合理的方式排序行来观察文件大小的显着减少,并通过在排列行之后以“某种”方式对列进行排序来进行微小的减少。
是否有自动方法来确定最佳的列顺序以及排列它们的最佳顺序?该方法可能使用动态编程或其他东西,但我希望有一个R包,它有一个随时可用的实现。
一旦加载到内存中,预先安排好的对象一般性能更高吗?对于做与预先安排的分组一致的事情,我猜是'是'。
编辑,出于兴趣,这里有一些简单任务的时间结果:
# Do a process on a data.frame
process_func <- function(x){
x %>% group_by(
V2,V5,V1
) %>% summarise(
sum(V4),
sum(V3)
)
}
system.time(replicate(100, process_func(df_1)))
system.time(replicate(100, process_func(df_2)))
system.time(replicate(100, process_func(df_3)))
同样的任务需要(重复100次):
答案 0 :(得分:2)
作为一种优秀的启发式方法,我会首先通过具有较少不同值的列来排序。更优化的解决方案需要更多的计算时间,考虑到问题的大小,这将是困难的。
你可以这样做:
df_4 <- df_1 %>%
arrange_at(., names(sort(sapply(., n_distinct))))