首页 > 解决方案 > 具有可选分组参数的用户函数,如果在 R 中使用管道

问题描述

我最近开始编写自己的函数来加快标准和重复性任务,同时使用 R 分析数据。

目前我正在处理一个带有三个参数的函数,并遇到了一个我还无法解决的挑战。我想要一个可选的分组参数。在此过程中,函数应检查是否存在分组参数,然后继续使用子函数 1 或 2。

但是,如果分组参数不是 NA,我总是会收到错误“找不到对象”。我怎样才能做到这一点?

编辑:在我的情况下,过滤器通常用于过滤某些有效或无效的年份。如果有分组参数,则管道中将遵循比没有分组参数更多的步骤。

require(tidyverse)

Data <- mpg

userfunction <- function(DF,Filter,Group) {
  
  without_group <- function(DF) {
    DF %>% 
      count(year)
  }
  
  with_group <- function(DF) {
    DF %>% 
      group_by({{Group}}) %>% 
      count(year) %>% 
      pivot_wider(names_from=year, values_from=n) %>%
      ungroup() %>% 
      mutate(across(.cols=2:ncol(.),.fns=~replace_na(.x, 0))) %>% 
      mutate(Mittelwert=round(rowMeans(.[,2:ncol(.)],na.rm=TRUE),2))
  }
  
  Obj <- DF %>% 
    ungroup() %>% 
    {if(Filter!=FALSE) filter(.,eval(rlang::parse_expr(Filter))) else filter(.,.$year==.$year)} %>%
    {if(is.na(Group)) without_group(.) else with_group(.)} 
  
  return(Obj)
    
}

对于 NA,它已经有效:

> Data %>% 
+   userfunction(FALSE,NA)
# A tibble: 2 x 2
   year     n
  <int> <int>
1  1999   117
2  2008   117

使用参数它不起作用:

> Data %>% 
+   userfunction(FALSE,manufacturer)
 Error in DF %>% ungroup() %>% { : object 'manufacturer' not found

编辑:我对上述函数的期望是以下输出:

> Data %>% userfunction_exp(FALSE,manufacturer)
# A tibble: 15 x 4
   manufacturer `1999` `2008` Mittelwert
   <chr>         <dbl>  <dbl>      <dbl>
 1 audi              9      9        9  
 2 chevrolet         7     12        9.5
 3 dodge            16     21       18.5
 4 ford             15     10       12.5
 5 honda             5      4        4.5
 6 hyundai           6      8        7  
 7 jeep              2      6        4  
 8 land rover        2      2        2  
 9 lincoln           2      1        1.5
10 mercury           2      2        2  
11 nissan            6      7        6.5
12 pontiac           3      2        2.5
13 subaru            6      8        7  
14 toyota           20     14       17  
15 volkswagen       16     11       13.5

 Data %>% userfunction_exp("cyl==4",manufacturer)
# A tibble: 9 x 4
  manufacturer `1999` `2008`  mean
  <chr>         <dbl>  <dbl> <dbl>
1 audi              4      4   4  
2 chevrolet         1      1   1  
3 dodge             1      0   0.5
4 honda             5      4   4.5
5 hyundai           4      4   4  
6 nissan            2      2   2  
7 subaru            6      8   7  
8 toyota           11      7   9  
9 volkswagen       11      6   8.5

2021-04-01 14:55:编辑添加一些信息,并为函数 with_group 添加一些步骤。

标签: r

解决方案


我不知道Filter参数有什么用,所以我暂时保持原样。

group_by(A) %>% count(B)相同,count(A, B)因此您可以将功能更改为:

library(tidyverse)

userfunction <- function(DF,Filter,Group = NULL) {
  DF %>% 
    count(year, {{Group}}) %>% 
    pivot_wider(names_from=year, values_from=n)
}

Data %>% userfunction(FALSE)

#   `1999` `2008`
#   <int>  <int>
#1    117    117

Data %>% userfunction(FALSE,manufacturer)
# A tibble: 15 x 3
#   manufacturer `1999` `2008`
#   <chr>         <int>  <int>
# 1 audi              9      9
# 2 chevrolet         7     12
# 3 dodge            16     21
# 4 ford             15     10
# 5 honda             5      4
# 6 hyundai           6      8
# 7 jeep              2      6
# 8 land rover        2      2
# 9 lincoln           2      1
#10 mercury           2      2
#11 nissan            6      7
#12 pontiac           3      2
#13 subaru            6      8
#14 toyota           20     14
#15 volkswagen       16     11

请注意,我已将默认值分配给GroupasNULL因此,当您不提及任何内容时,它会忽略该参数。


推荐阅读