purrr :: map变体,返回长的data.frame

时间:2019-05-23 18:26:56

标签: r tidyr purrr

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*变体,它自然返回一个长data.frame

1 个答案:

答案 0 :(得分:4)

这不是map_df函数的问题,而是bind_rows的问题。 _dfr变体所做的全部工作是先调用map,然后调用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 package(v0.3.0)于2019-05-23创建

希望有帮助!