高效地合并命名列表

Efficiently merging named lists

我有两个非常大的数据集,我正在寻找一种有效合并它们的方法(内部连接很好)。 我想出了一个解决方案,即在合并键上创建命名吐出列表并将它们合并。

不幸的是,该解决方案仍然非常低效。 有没有一种方法可以完全避免使用 dplyr 我认为这是问题的根源,以及缓慢的 lapply。 map 是一个好的解决方案吗?

在这里你可以找到一个可重现的例子 提前致谢!

library(tidyverse)
library(data.table)

named_group_split <- function(.tbl, ...) {
  
  # get names
  grouped <- group_by(.tbl, ...)
  names <- rlang::eval_bare(rlang::expr(paste(!!!group_keys(grouped), sep = "-")))
  
  # split data
  grouped %>% 
    group_split(.keep = FALSE) %>% 
    rlang::set_names(names)
}


# FIRST SPLIT LIST
set.seed(1)
db_1 <- data.frame(id_1=sample(1:10, 10, replace=T),
                   id_2=sample(LETTERS, 10, replace=T),
value1=runif(10, 1.0, 10.0)) %>% 
  data.table() %>% 
  dplyr::mutate(id_1name=id_1,
                id_2name=id_2) %>% 
  named_group_split(id_1name,id_2name)

# SECOND SPLIT LIST
set.seed(2)
db_2 <- data.frame(id_1=sample(1:10, 1000, replace=T),
                   id_2=sample(LETTERS, 1000, replace=T),
                   value2=runif(1000, 1.0, 10.0)) %>% 
  data.table() %>% 
  dplyr::mutate(id_1name=id_1,
                id_2name=id_2) %>% 
  named_group_split(id_1name,id_2name)


keys <- intersect(unique(c(names(db_1))), unique(c(names(db_2))))

result <- setNames(lapply(keys, function(key){
  result <- db_1[[key]] %>% 
    dplyr::left_join(db_2[[key]])
}),keys) %>% 
  do.call(plyr:::rbind.fill,.) 

我设法做到了以下几点:

library(purrr)

my_lists <- function(list1, list2) {  
  keys <- intersect(unique(c(names(list1))), unique(c(names(list2))))
  result <- map2(list1[keys], list2[keys], c) 
  
  return(result)
  
}

result <- my_lists(db1, db2)

但是我无法从那里重新创建我需要的数据库...

也许我遗漏了什么,但我认为您正在寻找合适的加入。

library(data.table)
set.seed(1)
x <- data.table(id_1=sample(1:10, 10, replace=T),
                id_2=sample(LETTERS, 10, replace=T))
set.seed(2)
y <- data.table(id_1=sample(1:10, 1000, replace=T),
                id_2=sample(LETTERS, 1000, replace=T),
                value=runif(1000, 1.0, 10.0))

res <- y[x, on = c("id_1", "id_2")]
setorderv(res, c("id_1", "id_2"))
res

    id_1 id_2    value
 1:    1    N 8.441071
 2:    1    N 5.680715
 3:    1    U 3.681615
 4:    1    U 7.159788
 5:    1    U 2.732143
 6:    1    U 1.246033
 7:    2    I 5.810975
 8:    2    I 7.015206
 9:    2    J 4.238503
10:    2    J 6.705899
11:    2    J 7.852617
12:    3    O 8.645228
13:    3    O 7.496095
14:    3    O 2.553506
15:    4    J 2.158799
16:    4    J 4.876194
17:    4    J 4.118119
18:    4    J 8.434567
19:    4    J 9.263452
20:    4    J 3.661710
21:    5    E 1.112813
22:    5    E 4.654503
23:    7    G 1.307912
24:    7    G 6.233104
25:    7    G 3.577720
26:    7    G 1.918811
27:    7    G 7.521629
28:    7    V 2.511941
29:    7    V 2.785865
30:    7    V 6.875612
31:    7    V 4.133124
32:    7    V 8.655604
33:    9    U 3.090105
34:    9    U 5.347673

这在我的电脑上快了大约 250 倍,但实际设置的效果可能会有所不同。

Is there a way I can avoid using dplyr at all I believe that is the root of the issue, as well as the slow lapply. Is map a good solution?

通常,当 dplyr 太慢时,值得一看 data.table,或 dtplyr,它将 dplyr 语法转换为 data.table.如果处理不当,lapply 对于大型数据集可能是 。当变量被正确初始化时,选择的循环方法不应该是任务的主要瓶颈。如果是,请尝试 vapply.