Умножьте, выберите и опционально сгруппируйте произвольные переменные программно с помощью dplyr - PullRequest
1 голос
/ 19 марта 2019

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

Тестовый фрейм данных:

library(ggplot2)
msleep_mini <- msleep[1:10, ]

Функция должна воспроизводить следующее поведение.Если вызывается с одним аргументом, скажем, sleep_total, он просто умножает sleep_total на 2 и возвращает кадр данных, содержащий столбцы name, vore, order и sleep_total:

# test_1
msleep_mini %>%
  group_double_select(sleep_total)
#> # A tibble: 20 x 4
#>    name                       vore  order           sleep_total
#>    <chr>                      <chr> <chr>                 <dbl>
#>  1 Cheetah                    carni Carnivora              24.2
#>  2 Owl monkey                 omni  Primates               34  
#>  3 Mountain beaver            herbi Rodentia               28.8
#>  4 Greater short-tailed shrew omni  Soricomorpha           29.8
#>  5 Cow                        herbi Artiodactyla            8  
#>  6 Three-toed sloth           herbi Pilosa                 28.8
#>  7 Northern fur seal          carni Carnivora              17.4
#>  8 Vesper mouse               <NA>  Rodentia               14  
#>  9 Dog                        carni Carnivora              20.2
#> 10 Roe deer                   herbi Artiodactyla            6  

Если вызывается с двумя аргументами, второй интерпретируется как группирующая переменная.Опять же, первый умножается на 2, но теперь фрейм данных также группируется по второму аргументу, отсортированному по нему, и, наконец, к фрейму данных добавляется столбец id, содержащий прогрессивный номер строки внутри каждой группы.Другими словами, результат будет

# test_2
msleep_mini %>%
  group_double_select(sleep_total, vore)
#> # A tibble: 20 x 5
#> # Groups:   vore [4]
#>    vore  name                       order           sleep_total    id
#>    <chr> <chr>                      <chr>                 <dbl> <int>
#>  1 carni Cheetah                    Carnivora              24.2     1
#>  2 carni Northern fur seal          Carnivora              17.4     2
#>  3 carni Dog                        Carnivora              20.2     3
#>  4 carni Long-nosed armadillo       Cingulata              34.8     4
#>  5 herbi Mountain beaver            Rodentia               28.8     1
#>  6 herbi Cow                        Artiodactyla            8       2
#>  7 herbi Three-toed sloth           Pilosa                 28.8     3
#>  8 herbi Roe deer                   Artiodactyla            6       4
#>  9 herbi Goat                       Artiodactyla           10.6     5
#> 10 herbi Guinea pig                 Rodentia               18.8     6

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

# test_3
msleep_mini %>%
  group_double_select(sleep_rem, order)
#> # A tibble: 20 x 5
#> # Groups:   order [9]
#>    order           name                       vore  sleep_rem    id
#>    <chr>           <chr>                      <chr>     <dbl> <int>
#>  1 Artiodactyla    Cow                        herbi       1.4     1
#>  2 Artiodactyla    Roe deer                   herbi      NA       2
#>  3 Artiodactyla    Goat                       herbi       1.2     3
#>  4 Carnivora       Cheetah                    carni      NA       1
#>  5 Carnivora       Northern fur seal          carni       2.8     2
#>  6 Carnivora       Dog                        carni       5.8     3
#>  7 Cingulata       Long-nosed armadillo       carni       6.2     1
#>  8 Didelphimorphia North American Opossum     omni        9.8     1
#>  9 Hyracoidea      Tree hyrax                 herbi       1       1
#> 10 Pilosa          Three-toed sloth           herbi       4.4     1

ЭтоМне кажется, что единственный способ написать group_double_select надежным и понятным способом - использовать аккуратную оценку, но я могу ошибаться.Вы можете мне помочь?

1 Ответ

1 голос
/ 19 марта 2019

Мы можем использовать missing, чтобы проверить, отсутствует ли аргумент в функции

group_double_select <- function(data, colVar, groupVar) {
   colVar <- enquo(colVar)



   if(missing(groupVar)) {
        data %>% 
              select(name, vore, order, !!colVar) %>% 
              mutate(!! quo_name(colVar) :=  !! colVar * 2)


   } else {
       groupVar <- enquo(groupVar)
       data %>%
            select(name, vore, order, !!colVar) %>%
            mutate(!! quo_name(colVar) :=  !! colVar * 2) %>%
            group_by(!! groupVar) %>%
            mutate(id = row_number()) %>%
            arrange(!! groupVar)





}

}

-testing

msleep_mini %>%
       group_double_select(sleep_total, vore) %>%
       head
# A tibble: 6 x 5
# Groups:   vore [2]
#  name                 vore  order        sleep_total    id
#  <chr>                <chr> <chr>              <dbl> <int>
#1 Cheetah              carni Carnivora           24.2     1
#2 Northern fur seal    carni Carnivora           17.4     2
#3 Dog                  carni Carnivora           20.2     3
#4 Long-nosed armadillo carni Cingulata           34.8     4
#5 Mountain beaver      herbi Rodentia            28.8     1
#6 Cow                  herbi Artiodactyla         8       2



msleep_mini %>% 
       group_double_select(sleep_total) %>%
       head
# A tibble: 6 x 4
#  name                       vore  order        sleep_total
#  <chr>                      <chr> <chr>              <dbl>
#1 Cheetah                    carni Carnivora           24.2
#2 Owl monkey                 omni  Primates            34  
#3 Mountain beaver            herbi Rodentia            28.8
#4 Greater short-tailed shrew omni  Soricomorpha        29.8
#5 Cow                        herbi Artiodactyla         8  
#6 Three-toed sloth           herbi Pilosa              28.8




msleep_mini %>%
       group_double_select(sleep_rem, order) %>%
       head
# A tibble: 6 x 5
# Groups:   order [2]
#  name              vore  order        sleep_rem    id
#  <chr>             <chr> <chr>            <dbl> <int>
#1 Cow               herbi Artiodactyla       1.4     1
#2 Roe deer          herbi Artiodactyla      NA       2
#3 Goat              herbi Artiodactyla       1.2     3
#4 Cheetah           carni Carnivora         NA       1
#5 Northern fur seal carni Carnivora          2.8     2
#6 Dog               carni Carnivora          5.8     3
...