使用dplyr以编程方式对任意变量进行乘法、选择和分组(可选)

使用dplyr以编程方式对任意变量进行乘法、选择和分组(可选),r,select,group-by,dplyr,tidyeval,R,Select,Group By,Dplyr,Tidyeval,在我使用dplyr的代码中,我经常对一个数据帧变量执行某些操作(这里假设为简单的乘以2,以简化MRE),可以选择对另一个变量分组,然后仅选择部分结果变量。为了防止代码重复,我想写一个函数 测试数据帧是 library(ggplot2) msleep_mini <- msleep[1:10, ] 如果使用两个参数调用,则第二个参数将解释为分组变量。同样,第一个参数乘以2,但是现在数据帧也被第二个参数分组,并根据它进行排序,最后一个id列(包含每个组中的累进行号)被添加到数据帧中。换句话说,

在我使用
dplyr
的代码中,我经常对一个数据帧变量执行某些操作(这里假设为简单的乘以2,以简化MRE),可以选择对另一个变量分组,然后
仅选择部分结果变量。为了防止代码重复,我想写一个函数

测试数据帧是

library(ggplot2)
msleep_mini <- msleep[1:10, ]
如果使用两个参数调用,则第二个参数将解释为分组变量。同样,第一个参数乘以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
#测试2
msleep_迷你%>%
组双选择(睡眠总数,vore)
#>#A tibble:20 x 5
#>#组:vore[4]
#>vore名称顺序睡眠\u总id
#>                                             
#>1食肉猎豹食肉动物24.2 1
#>2肉食动物北方毛皮海豹肉食动物17.4 2
#>3食肉狗食肉动物20.2 3
#>4卡尼长鼻扣带犰狳34.8 4
#>5赫比山海狸啮齿动物28.8 1
#>6赫比牛偶蹄目8 2
#>7赫比三趾树懒Pilosa 28.8 3
#>8黑鹿偶蹄目6 4
#>9赫比山羊偶蹄目10.6 5
#>10赫比豚鼠啮齿动物18.8 6
当然,函数必须使用任意变量(只要可以在数据帧中找到):

#测试3
msleep_迷你%>%
组双选择(睡眠快速,顺序)
#>#A tibble:20 x 5
#>#组:顺序[9]
#>订单名称vore sleep\u rem id
#>                                           
#>1偶蹄目奶牛1.4 1
#>2偶蹄目狍2
#>3偶蹄目山羊herbi 1.2 3
#>4食肉动物猎豹肉食NA 1
#>5肉食动物北方毛皮海豹肉食动物2.8 2
#>6肉食动物狗肉食5.8 3
#>7扣带回长鼻犰狳6.2 1
#>8双足类北美负鼠omni 9.8 1
#>9.土鳖总科树土鳖1
#>10 Pilosa三趾树懒herbi 4.4 1

在我看来,以健壮且可维护的方式编写
group\u double\u select
的唯一方法是使用整洁的评估,但我可能错了。您能帮助我吗?

我们可以使用
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)





}

}
group\u double\u select%
变异(!!quo_名称(colVar):=!!colVar*2)
}否则{
组变量%
选择(名称、vore、订单、!!colVar)%>%
变异(!!quo_名称(colVar):=!!colVar*2)%>%
分组依据(!!groupVar)%>%
变异(id=行号())%>%
安排(!!groupVar)
}
}
-测试

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
msleep\u mini%>%
组双选择(睡眠总数,vore)%>%
头
#一个tibble:6x5
#组别:vore[2]
#名称vore订单睡眠\u总id
#                                  
#1猎豹肉食动物24.2 1
#2北方毛皮海豹肉食动物17.4 2
#3狗食肉动物20.2 3
#4长鼻扣带回犰狳34.8 4
#5山地海狸啮齿动物28.8 1
#6母牛赫比偶蹄目8 2
msleep_迷你%>%
组双选择(睡眠总数)%>%
头
#一个tibble:6x4
#姓名/顺序/睡眠总数
#                                       
#1猎豹肉食动物24.2
#2猫头鹰猴全灵长类34
#3山海狸啮齿动物28.8
#4大短尾鼩全囊形目29.8
#5母牛赫比偶蹄目8
#6三趾树懒herbi Pilosa 28.8
msleep_迷你%>%
组双选择(睡眠rem,顺序)%>%
头
#一个tibble:6x5
#分组:顺序[2]
#名称vore订单睡眠\u rem id
#                             
#1头母牛赫比偶蹄动物1.4 1
#2偶蹄亚目鹿2
#3山羊herbi偶蹄动物1.2 3
#4猎豹肉食动物NA 1
#5北方毛皮海豹肉食动物2.8 2
#6狗食肉动物5.8 3

您是否可以编辑以减少行数(如果它们不是理解问题所必需的)@NelsonGon当然,我可以看到msleep_mini的变化
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)





}

}
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