purrr :: map вариант, который возвращает длинный data.frame - PullRequest
0 голосов
/ 23 мая 2019

Оба purrr::map_dfr и purrr::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 Ответ

4 голосов
/ 23 мая 2019

Это проблема не с функциями 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

Создано в 2019-05-23 с помощью пакета Представить (v0.3.0)

Надеюсь, это поможет!

...