我有一个整齐的格式的小标题,具有三个属性-一个系列,其可能的下一个元素之一以及下一个元素的概率。
library(dplyr)
bases <- sapply(1:20, function(x){paste(sample(letters[1:3], 3, replace = T), collapse = " ")})
nplus1 <- sample(letters, 20, replace = T)
probs <- runif(20)
t <- as_tibble(data.frame(bases, nplus1, probs))
head(t)
# A tibble: 6 x 3
bases nplus1 probs
<fct> <fct> <dbl>
1 b a c r 0.409
2 c b b p 0.176
3 a b c s 0.468
4 a b a n 0.348
5 b a b c 0.733
6 b a b e 0.0525
最终,我想使用list2env()
按基数进行哈希查找。为此,我使用split()
将表分为按基分组的表列表。小标题大约有数百万行,split()
足够快。
t_split <- split(t, t$bases)
t_split[1:3]
$`a a c`
# A tibble: 1 x 3
bases nplus1 probs
<fct> <fct> <dbl>
1 a a c i 0.661
$`a b a`
# A tibble: 1 x 3
bases nplus1 probs
<fct> <fct> <dbl>
1 a b a n 0.348
$`a b c`
# A tibble: 2 x 3
bases nplus1 probs
<fct> <fct> <dbl>
1 a b c s 0.468
2 a b c h 0.0324
从那里开始,将for循环应用于小标题列表,以便将内存密集型表转换为列表。我的理解是,在进行这种就地转换时,for循环比lapply
更快。
# helper function transforms tibble to vector
flatten <- function(table){
l <- list(np1 = table$nplus1, probs=table$probs)
return(l)
}
# for loop
loop <- function(table.list){
list.names <- names(table.list)
for( n in list.names ){
table.list[[n]] <- flatten(table.list[[n]])
}
table.list <- setNames(table.list, list.names)
return(table.list)
}
loop(t_split)
虽然按组拆分的速度很快,但是使单个小标题变平的四个循环却需要花费永恒的时间,对于具有约150万行的未拆分表,大约需要12个小时。
这里有什么特别低效的东西吗?是否有更好,更快的方式来重新格式化这些数据?