使用Dplyr :: Bind_Rows和Purrr在数据帧列表中有选择地绑定不同的数据帧

时间:2018-01-29 03:47:34

标签: r dplyr tidyverse purrr

library(tidyverse)

我尝试使用tidyverse工具使用dplyr :: bind_rows()选择性地绑定数据帧列表。我将拆分mtcars数据集以创建我的真实数据的基本再现。

Df<-mtcars%>%
split(.$carb)%>%
head()

我可以将它与bind_rows()...

绑定在一起
Df<-Df%>%
bind_rows()

但是如何有选择地绑定列表的元素。我想要做的是创建两个列表 - 第一个绑定列表元素1,3,6,而第二个绑定2,4,8。 我想的就是......

Df<-Df%>%map(~bind_rows(.x,list(.$`1`,.$`3`,.$`6`),list(.$`2`,.$`4`,.$`8`)))

但是这段代码显然不正确,所以我很感激一些建议。

3 个答案:

答案 0 :(得分:1)

好的,所以我意识到OP只是给出了一个例子,最初的起点是

Df<- mtcars%>% split(.$carb)

如果我们这样做,原始解决方案仍然有效

lst <- list(x = c(1, 3, 6), y = c(2, 4, 8))

Df %>%
  bind_rows() %>%
  split(.$carb %in% lst[[1]])

但有没有办法可以直接根据lst绑定它们?

我不是tidyverse的专家,但经过documentation后,我找到了一个函数invoke_map,它可以提供我们想要的内容。

invoke_map(list(
  function(x){x %>% map(. %>% filter(carb %in% lst[[1]])) %>% map_df(c)},
  function(x){x %>% map(. %>% filter(carb %in% lst[[2]])) %>% map_df(c)})

#[[1]]
# A tibble: 11 x 11
#     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1  22.8     4 108.0    93  3.85 2.320 18.61     1     1     4     1
# 2  21.4     6 258.0   110  3.08 3.215 19.44     1     0     3     1
# 3  18.1     6 225.0   105  2.76 3.460 20.22     1     0     3     1
# 4  32.4     4  78.7    66  4.08 2.200 19.47     1     1     4     1
# 5  33.9     4  71.1    65  4.22 1.835 19.90     1     1     4     1
# 6  21.5     4 120.1    97  3.70 2.465 20.01     1     0     3     1
# 7  27.3     4  79.0    66  4.08 1.935 18.90     1     1     4     1
# 8  16.4     8 275.8   180  3.07 4.070 17.40     0     0     3     3
# 9  17.3     8 275.8   180  3.07 3.730 17.60     0     0     3     3
#10  15.2     8 275.8   180  3.07 3.780 18.00     0     0     3     3
#11  19.7     6 145.0   175  3.62 2.770 15.50     0     1     5     6

#[[2]]
# A tibble: 21 x 11
#     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1  18.7     8 360.0   175  3.15 3.440 17.02     0     0     3     2
# 2  24.4     4 146.7    62  3.69 3.190 20.00     1     0     4     2
# 3  22.8     4 140.8    95  3.92 3.150 22.90     1     0     4     2
# 4  30.4     4  75.7    52  4.93 1.615 18.52     1     1     4     2
# 5  15.5     8 318.0   150  2.76 3.520 16.87     0     0     3     2
# 6  15.2     8 304.0   150  3.15 3.435 17.30     0     0     3     2
# 7  19.2     8 400.0   175  3.08 3.845 17.05     0     0     3     2
# 8  26.0     4 120.3    91  4.43 2.140 16.70     0     1     5     2
# 9  30.4     4  95.1   113  3.77 1.513 16.90     1     1     5     2
#10  21.4     4 121.0   109  4.11 2.780 18.60     1     1     4     2
# ... with 11 more rows

给出了预期的输出。可能有更好的方法来优化这一点,我不确定。

原始答案:

为什么不改变split步骤?不使用bind_rows()获取输出。

lst <- list(x = c(1, 3, 6), y = c(2, 4, 8))

mtcars %>%
  split(.$carb %in% lst[[1]])


#$`FALSE`
#                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
#Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
#Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
#Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
#Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
#Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

#$`TRUE`
#                mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#Datsun 710     22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#Valiant        18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#Merc 450SE     16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#Merc 450SL     17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#Merc 450SLC    15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#Fiat 128       32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#Toyota Corona  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#Fiat X1-9      27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#Ferrari Dino   19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6

答案 1 :(得分:1)

这可能是另一种方式。我试图在这里反映您的map()主题。我在基数R中使用了Map()。如果您想使用purrr包,我认为您可以尝试map2()

foo <- mtcars %>% split(.$carb)

Map(function(x, y) bind_rows(foo[c(x, y)]), c(TRUE, FALSE), c(FALSE, TRUE))

map2(.x = c(TRUE, FALSE), .y = c(FALSE, TRUE), .f = ~ bind_rows(foo[c(.x, .y)]))

[[1]]
    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
2  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
3  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
4  32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
5  33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
6  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
7  27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
8  16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
9  17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
10 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
11 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6

[[2]]
    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
2  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
3  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
4  30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
5  15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
6  15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
7  19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
8  26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
9  30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
10 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
11 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
12 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
13 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
14 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
15 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
16 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
17 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
18 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
19 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
20 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
21 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8

答案 2 :(得分:0)

一种简单的方法是在隐式函数中使用一个固定参数进行映射。

picker <- list(c('1', '3', '6'), c('2', '4', '8'))
my_out <- map(picker, ~'['(Df, .x) %>% bind_rows) 

my_out %>% print 
基于其他答案的

我认为你现在想要的是:

[[1]]
    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
2  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
3  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
4  32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
5  33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
6  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
7  27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
8  16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
9  17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
10 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
11 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6

[[2]]
    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
2  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
3  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
4  30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
5  15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
6  15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
7  19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
8  26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
9  30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
10 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
11 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
12 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
13 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
14 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
15 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
16 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
17 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
18 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
19 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
20 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
21 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8

注意:我最初对您是否希望我将picker称为列表的 indices 或您想要名称列表感到困惑。这种混淆只是split()名单列表的工件,可能并不适用于您的真实数据。