Подтвердить что ты не робот

Использовать dplyr summaryise_each, чтобы вернуть одну строку за каждую функцию?

Я использую dplyr summaryise_each для применения функции к нескольким столбцам данных. Одно замечательно, что вы можете сразу применить несколько функций. Дело в том, что это раздражает, что вывод представляет собой кадр данных с одной строкой. Кажется, что он должен возвращать столько строк, сколько функций, с таким количеством столбцов, как столбцы, которые были суммированы.

library(dplyr)  
default <- 
  iris %>% 
  summarise_each(funs(min, max), matches("Petal"))

это возвращает

> default
  Petal.Length_min Petal.Width_min Petal.Length_max Petal.Width_max
1                1             0.1              6.9             2.5

Я бы предпочел что-то вроде

library(reshape2)
desired <- 
  iris %>% 
  select(matches("Petal")) %>% 
  melt() %>% 
  group_by(variable) %>% 
  summarize(min=min(value),max=max(value)) %>%
  t()

который возвращает что-то близкое (а не фреймворк данных, но вы все понимаете)

> desired
         [,1]           [,2]         
variable "Petal.Length" "Petal.Width"
min      "1.0"          "0.1"        
max      "6.9"          "2.5" 

есть ли опция в summaryise для этого? Если нет, Хэдли, не могли бы вы добавить его?

4b9b3361

Ответ 1

Вы можете получить аналогичный вывод, объединяющий пакеты dplyr и tidyr. Что-то в этих строках может помочь

library(dplyr)
library(tidyr)

iris %>%
  select(matches("Petal")) %>%
  summarise_each(funs(min, max)) %>%
  gather(variable, value) %>%
  separate(variable, c("var", "stat"), sep = "\\_") %>%
  spread(var, value)
##   stat Petal.Length Petal.Width
## 1  max          6.9         2.5
## 2  min          1.0         0.1

Ответ 2

Насколько мне известно, такого аргумента нет. Во всяком случае, здесь обходной путь, который выводит аккуратные данные, я думаю, что это будет даже лучше, чем столько строк, сколько функций и столько столбцов, сколько суммированных столбцов. (обратите внимание, что add_rownames требует dplyr 0.4.0)

library("dplyr")
library("tidyr")

iris %>% 
  summarise_each(funs(min, max, mean, median), matches("Petal")) %>%
  t %>% 
  as.data.frame %>% 
  add_rownames %>%
  separate(rowname, into = c("feature", "fun"), sep = "_")

возвращает:

       feature    fun       V1
1 Petal.Length    min 1.000000
2  Petal.Width    min 0.100000
3 Petal.Length    max 6.900000
4  Petal.Width    max 2.500000
5 Petal.Length   mean 3.758000
6  Petal.Width   mean 1.199333
7 Petal.Length median 4.350000
8  Petal.Width median 1.300000

Ответ 3

Один из вариантов заключается в использовании purrr::map_df (действительно map_dfc, чтобы упростить возврат к data.frame с помощью bind_cols, хотя map_df сейчас прекрасен) с помощью функции, которая делает вектор результатов каждой функции, то есть

library(tidyverse)

iris %>% select(contains('Petal')) %>% 
    map_dfc(~c(min(.x), max(.x))) %>% 
    mutate(stat = c('min', 'max'))    # to add column of function names

#> # A tibble: 2 × 3
#>   Petal.Length Petal.Width  stat
#>          <dbl>       <dbl> <chr>
#> 1          1.0         0.1   min
#> 2          6.9         2.5   max