首页 > 解决方案 > purrr::map 变体返回长 data.frame

问题描述

两者兼而有之purrr::map_dfrpurrr::map_dfc广而告之data.frame

library(tidyverse)

mtcars %>% 
  map_dfr(~is.na(.) %>% mean)

mtcars %>% 
  map_dfc(~is.na(.) %>% mean)

两者都返回

# A tibble: 1 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     0     0     0     0     0     0     0     0     0     0     0

我可以用一个tidyr::gather

mtcars %>% 
  map_dfr(~is.na(.) %>% mean) %>% 
  gather

返回

# A tibble: 11 x 2
   key   value
   <chr> <dbl>
 1 mpg       0
 2 cyl       0
 3 disp      0
 4 hp        0
 5 drat      0
 6 wt        0
 7 qsec      0
 8 vs        0
 9 am        0
10 gear      0
11 carb      0

是否有一个purrr::map*本机返回 long 的变体data.frame

标签: rtidyrpurrr

解决方案


这不是map_df函数的问题,而是bind_rows. 变_dfr体所做的就是调用mapthen bind_rows。从文档中?bind_rows

请注意,由于历史原因,包含向量的列表始终被视为数据框。因此,它们的向量被视为列 而不是行,并且它们的内部名称被忽略。您可以通过显式拼接来规避这种行为。

因为您的函数返回一个向量列表,所以bind_rows会将每个向量视为列并返回一个宽数据框。除了您的方法之外gather,您还有其他一些选择:

imap_dfr通过使用来迭代列及其名称,使您的函数返回一个数据框。这是一个班轮,但可能更慢。

library(tidyverse)
mtcars %>%
  imap_dfr(~tibble(name = .y, value = is.na(.x) %>% mean))
#> # A tibble: 11 x 2
#>    name  value
#>    <chr> <dbl>
#>  1 mpg       0
#>  2 cyl       0
#>  3 disp      0
#>  4 hp        0
#>  5 drat      0
#>  6 wt        0
#>  7 qsec      0
#>  8 vs        0
#>  9 am        0
#> 10 gear      0
#> 11 carb      0

或者,返回一个命名向量而不是一个列表map_dbl,然后用enframe. 对于这个用例,这是我的基准测试中最快的。

mtcars %>%
  map_dbl(~is.na(.) %>% sum) %>%
  enframe()
#> # A tibble: 11 x 2
#>    name  value
#>    <chr> <dbl>
#>  1 mpg       0
#>  2 cyl       0
#>  3 disp      0
#>  4 hp        0
#>  5 drat      0
#>  6 wt        0
#>  7 qsec      0
#>  8 vs        0
#>  9 am        0
#> 10 gear      0
#> 11 carb      0

reprex 包(v0.3.0)于 2019 年 5 月 23 日创建

希望有帮助!


推荐阅读