Как происходит применение функции dplyr к списку значений? - PullRequest
1 голос
/ 24 апреля 2019

Я создал функцию dplyr для оценки количества событий для населения.Код работает, когда используется с явным именованием переменных в функциях dplyr :: filter и dplyr :: group_by.

Мне нужно применить функцию к 24 переменным, которые являются заголовками столбцов в кадре данных.Здесь они упоминаются как x.

Я использовал !!насколько я понимаю, переменная оценивается как строка, а не имя столбца.

Функция

summary_table <- function(x){
  assign(paste(x,"sum_tab", sep="_"),
         envir = parent.frame(),
         value = df %>%
  filter(!is.na(!!x)) %>%
  group_by(!!x) %>%
  summarise(
           'Variable name' = paste0(x),
            Discharged = sum(admission_status == "Discharged"),
           'Re-attended' = sum(!is.na(re_admission_status)),
           'Admitted on Re-attendance' = sum(re_admission_status == "Admitted", na.rm = TRUE)))
}


Я использовал:

sapply(var_names, summary_table)

Однако при этом выводится только одна строка таблицы для каждой переменной в списке var_names

В заключение я бы хотел, чтобы указатели указывали на правильный механизм для применения функции, написанной выше, к списку имен столбцов.в трубе dplyr.

Воспроизводимый пример

example <- mtcars %>%
  group_by(vs) %>%
  summarise(
    '6 cylinder' = sum(cyl == 6),
    'Large disp' = sum(disp >= 100),
    'low gears' = sum(gear <= 4))
})

В этом примере мы хотели бы применить эту функцию к следующему списку

cars_var <- c("vm", "am", "carb")

Это даст три таблицы для каждого столбца в списке.

1 Ответ

2 голосов
/ 24 апреля 2019

Как заметил @ eipi10, автоматическое создание переменных обычно неразумно. Лучше создать одну переменную, представляющую собой список фреймов данных.

Кроме того, пользователям проще самим применять группы с помощью group_by() или group_by_at(), чтобы вам не приходилось беспокоиться о том, как они предоставляют имена переменных.

РЕДАКТИРОВАТЬ 2019-05-2

Один из способов - считать имена переменных группировки как «данные» и отобразить их, создав копию фактических данных, сгруппированных по каждой из переменных группировки.

library(dplyr)
library(purrr)

grouping_vars <- c("vs", "am", "carb")
map(grouping_vars, group_by_at, .tbl = mtcars) %>%
  map(summarise,
      '6 cylinder' = sum(cyl == 6),
      'Large disp' = sum(disp >= 100),
      'low gears' = sum(gear <= 4))
#> [[1]]
#> # A tibble: 2 x 4
#>      vs `6 cylinder` `Large disp` `low gears`
#>   <dbl>        <int>        <int>       <int>
#> 1     0            3           18          14
#> 2     1            4            9          13
#> 
#> [[2]]
#> # A tibble: 2 x 4
#>      am `6 cylinder` `Large disp` `low gears`
#>   <dbl>        <int>        <int>       <int>
#> 1     0            4           19          19
#> 2     1            3            8           8
#> 
#> [[3]]
#> # A tibble: 6 x 4
#>    carb `6 cylinder` `Large disp` `low gears`
#>   <dbl>        <int>        <int>       <int>
#> 1     1            2            4           7
#> 2     2            0            8           8
#> 3     3            0            3           3
#> 4     4            4           10           9
#> 5     6            1            1           0
#> 6     8            0            1           0

Создано в 2019-05-02 пакетом представ. (v0.2.1)

Оригинальный ответ

Вот функция, которая использует dplyr::groups(), чтобы узнать, какие переменные были сгруппированы. Затем он перебирает каждую переменную группировки, суммирует и добавляет результирующий фрейм данных в список.

library(dplyr)

margins <- function(.data, ...) {
  groups <- dplyr::groups(.data)
  n <- length(groups)
  out <- vector(mode = "list", length = n)
  for (i in rev(seq_len(n))) {
    out[[i]] <-
      .data %>%
      dplyr::group_by(!!groups[[i]]) %>%
      dplyr::summarise(...) %>%
      dplyr::group_by(!!groups[[i]]) # Reapply the original group
  }
  out
}

mtcars %>%
  group_by(vs, am, carb) %>%
  margins('6 cylinder' = sum(cyl == 6),
          'Large disp' = sum(disp >= 100),
          'low gears' = sum(gear <= 4))
#> [[1]]
#> # A tibble: 2 x 4
#> # Groups:   vs [2]
#>      vs `6 cylinder` `Large disp` `low gears`
#>   <dbl>        <int>        <int>       <int>
#> 1     0            3           18          14
#> 2     1            4            9          13
#> 
#> [[2]]
#> # A tibble: 2 x 4
#> # Groups:   am [2]
#>      am `6 cylinder` `Large disp` `low gears`
#>   <dbl>        <int>        <int>       <int>
#> 1     0            4           19          19
#> 2     1            3            8           8
#> 
#> [[3]]
#> # A tibble: 6 x 4
#> # Groups:   carb [6]
#>    carb `6 cylinder` `Large disp` `low gears`
#>   <dbl>        <int>        <int>       <int>
#> 1     1            2            4           7
#> 2     2            0            8           8
#> 3     3            0            3           3
#> 4     4            4           10           9
#> 5     6            1            1           0
#> 6     8            0            1           0

Создано в 2019-04-24 пакетом представительство (v0.2.1.9000)

Если вы хотите сгруппировать с вектором имен переменных, вы можете использовать dplyr::group_by_at() и dplyr::vars().

cars_var <- c("vs", "am", "carb")

mtcars %>%
  group_by_at(vars(cars_var)) %>%
  margins('6 cylinder' = sum(cyl == 6),
          'Large disp' = sum(disp >= 100),
          'low gears' = sum(gear <= 4))

Я являюсь автором небольшого пакета под названием armgin , который реализует эту и несколько похожих идей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...