创建整齐的多重归约函数

时间:2019-06-07 07:28:23

标签: r tidyverse purrr rlang

我想用一个函数替换这个(want):

library(tidyverse)
library(rlang)

set.seed(1)
create_a <- function() {
      list(x = 1:10, y = data.frame(aa = round(rnorm(10, 2000, 10), 0),
                                bb = sample(letters[3:8], 10, replace = T),
                                stringsAsFactors = F))
}

create_b <- function() {
  list(x = 1:10, y = data.frame(aa = round(rnorm(10, 10, 1), 0),
                                bb = sample(letters[3:8], 10, replace = T),
                                stringsAsFactors = F))
}  

want <- list(x = reduce(map(list(create_a(), create_b()), 1), c),
             y = reduce(map(list(create_a(), create_b()), 2), rbind)) # or bind_rows

有多个函数(create_acreate_b)创建具有相同名称元素的输出列表。与上述示例相反,实际函数中的计算完全不同。 该函数应如下所示:

multiple_reduce <- function(...) {
  # ????
}
want <- multiple_reduce(create_a(), 
                        create_b())

您如何使用整洁的方法来做到这一点?

want在两种情况下都应如下所示:

$x
 [1]  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10

$y
     aa bb
1  2014  e
2  1999  g
3  2004  e
4  1999  d
5  1986  g
6  1996  d
7  1996  g
8  1999  c
9  2011  d
10 2008  c
11    9  h
12   10  g
13   11  e
14   10  e
15   11  c
16   10  c
17    9  g
18   10  c
19    9  e
20   11  f

1 个答案:

答案 0 :(得分:3)

也许一种方法是将所有输入组合在一起,并根据它们的名称进行拆分,以便我们将名称相似的列表放在一起。然后,我们可以检查列表是否属于原子类型,并相应地将它们组合为一个向量或数据帧。

library(tidyverse)

multiple_reduce <- function(a, b, ...) {
   combine_list <- c(a, b, ...)
   new_list <- split(combine_list, names(combine_list))
   list(x = map(new_list, ~keep(., is.atomic)) %>% flatten %>% reduce(c),
        y = map(new_list, ~discard(., is.atomic)) %>% flatten %>% bind_rows)
}

multiple_reduce(create_a(), create_b())

#$x
# [1]  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10

#$y
#     aa bb
#1  2001  g
#2  1998  h
#3  2003  g
#4  1971  h
#5  1998  h
#6  2001  f
#7  1993  d
#8  1990  c
#9  2009  d
#10 2019  d
#11   10  h
#12    9  d
#13   10  g
#14    8  f
#15   11  e
#16    9  c
#17   12  c
#18   10  f
#19   10  c
#20    8  h

这也适用于多个此类列表

multiple_reduce(create_a(), create_b(), create_a(), create_b())