gpt4 book ai didi

r - 使用 r (data.table/dplyr) 中的列表列

转载 作者:行者123 更新时间:2023-12-04 09:43:43 25 4
gpt4 key购买 nike

我有一个按列表列 (20Gb) 组织的大型数据集。

1-我可以使用任何其他技巧来加速以下代码吗? Data.table 似乎提供了两倍的增长,但我假设还有其他技巧可用于类似的场景。

2-除了 saveRDS - 是否有任何其他更快的文件库(vroom、fst 和 fwrite 似乎不支持 listcols)支持 listcolumns?

3-我试过 dt[,.(test=tib_sort[tib_sort[, .I[.N]], stringi::stri_sub(dt$ch, length = 5)],by=id)] 但它会抛出不正确的维数错误。是否可以选择使用列表列by 并自动将其设置为 setDT 和键/索引?

library(dplyr)
library(purrr)
library(data.table)
library(tictoc)

玩具数据

set.seed(123)
tib <-
tibble(id = 1:20000) %>% mutate(k = map_int(id, ~ sample(c(10:30), 1)))
tib <-
tib %>% mutate(tib_df = map(k, ~ tibble(
ch = replicate(.x, paste0(
sample(letters[1:24],
size = sample(c(10:20), 1)),
collapse = ""
)),
num = sample(1:1e10, .x,replace = F)
)))

Dplyr

help <- function(df) {
df <- df %>% top_n(1, num) %>% select(ch)
stringi::stri_sub(df, length = 5)
}
tic("purrr")
tib <- tib %>% mutate(result = map_chr(tib_df, help))
toc(log = T, quiet = T)

数据表

dt <- copy(tib)
setDT(dt)
tic("setDT w key")
dt[, tib_df := lapply(tib_df, setDT)]
dt[, tib_sort := lapply(tib_df, function(x)
setindex(x, "num"))]
toc(log = T, quiet = T)
tic("dt w key")
dt[, result_dt_key := sapply(tib_df, function(x) {
x[x[, .I[.N]], stringi::stri_sub(ch, length = 5)]
})]
toc(log=T, quiet = T)

时间

    tic.log(format = T)
[[1]]
[1] "purrr: 25.499 sec elapsed"

[[2]]
[1] "setDT w key: 4.875 sec elapsed"

[[3]]
[1] "dt w key: 12.077 sec elapsed"

在还包括来自 dplyr 和 data.table 的未嵌套版本之后进行编辑和更新

1 purrr: 25.824 sec elapsed          
2 setDT wo key: 2.97 sec elapsed
3 dt wo key: 13.724 sec elapsed
4 setDT w key: 1.778 sec elapsed
5 dt w key: 11.489 sec elapsed
6 dplyr,unnest: 1.496 sec elapsed
7 dt,I,unnest: 0.329 sec elapsed
8 dt, join, unnest: 0.325 sec elapsed

tic("dt, join, unnest")
b <- unnest(tib)
setDT(b)
unnest.J <- b[b[, .(num=max(num)), by = 'id'], on=c('id','num')][,r2:=stringi::stri_sub(ch,length=5)][]
toc(log=T)

res <- list(unnest.J$r2,tib2$result2,dt$result_dt_key,dt$result_dt,tib$result)
sapply(res,identical,unnest.I$r2)
[1] TRUE TRUE TRUE TRUE TRUE

所以-我想吸取的教训是,尽管列表列作为用于分析的数据结构看起来很诱人,但它们懒惰

enter image description here

最佳答案

对列表列的操作往往很慢,因为函数必须遍历条目并且不能向量化。因此通常取消嵌套列表列是有意义的:

tic("unnest")
tib2 <- tib %>%
tidyr::unnest(tib_df) %>%
group_by(id) %>%
top_n(1, num) %>%
mutate(result = stringi::stri_sub(ch, length = 5))
toc(log = T, quiet = T)

结果:

> tic.log(format = T)
[[1]]
[1] "purrr: 39.54 sec elapsed"

[[2]]
[1] "setDT w key: 10.7 sec elapsed"

[[3]]
[1] "dt w key: 19.19 sec elapsed"

[[4]]
[1] "unnest: 1.62 sec elapsed"

对于您的玩具数据,最终对象仅略有不同。但是,如果有必要取回原始表单,您可能需要执行以下操作:

tic("unnest+reattach")
tib2 <- tib %>%
tidyr::unnest(tib_df) %>%
group_by(id) %>%
top_n(1, num) %>%
mutate(result = stringi::stri_sub(ch, length = 5))

tib3 <- tib %>%
mutate(result = tib2$result[match(id, tib2$id)])

toc(log = T, quiet = T)

tic.log(format = T)[[5]]
[1] "unnest+reattach: 1.83 sec elapsed"

关于r - 使用 r (data.table/dplyr) 中的列表列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57477828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com