通过 `...` 扩展 tidyverse 函数 [英] Extending a tidyverse function via `...`

查看:13
本文介绍了通过 `...` 扩展 tidyverse 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过允许用户定义任意数量的参数来代替 ... 来扩展下面的 foo 函数.

I'm trying to extend my foo function below by allowing user to define any number of arguments in place of ....

这些 ... 参数将被视为当前的 3 个参数 (time, outcome, trt_gr>).

These ... arguments will exactly be treated as the current 3 arguments (time, outcome, trt_gr).

这在 R 中可行吗?

foo <- function(time = 1, outcome = 1, trt_gr = 1, ...){

  time <- seq_len(time)
  outcome <- seq_len(outcome)
  trt_gr <- seq_len(trt_gr)
  
data <- expand.grid(time = time, outcome = outcome, trt_gr = trt_gr, info. = c("control","treatment"))

data %>% 
  group_by(outcome, time, trt_gr) %>%
  summarise(info. = str_c(sort(info., decreasing = TRUE), 
                          collapse = ' vs. '), .groups = 'drop') 
}

# EXAMPLE OF CURRENT USE:

foo()

#  outcome  time trt_gr info.                
#    <int> <int>  <int> <chr>                
#1       1     1      1 treatment vs. control

推荐答案

是的,这是可能的.我们可以用省略号 ... 替换您的参数,并允许该函数生成任意数量的具有自定义列名的列.这里有一个 tidyverse 风格的函数:

Yes this is possible. We can replace your arguments with the elipsis ... and allow the function to produce any amount of columns of with custom column names. Here is such a function in the tidyverse style:

library(tidyverse)

foo <- function(...){
  
  dots <- rlang::list2(...) 
  var_nms <- names(dots)
  inp <- purrr::map(dots, seq_len)

  data <- tidyr::expand_grid(!!! inp,
                             info. = c("control","treatment"))
  
  data %>% 
    dplyr::group_by(!!!syms(var_nms)) %>%
    dplyr::summarise(info. = stringr::str_c(sort(info., decreasing = TRUE), 
                                            collapse = ' vs. '), .groups = 'drop') 
}

foo(time = 1, outcome = 1, trt_gr = 1)
#> # A tibble: 1 x 4
#>    time outcome trt_gr info.                
#>   <int>   <int>  <int> <chr>                
#> 1     1       1      1 treatment vs. control

foo(some = 2, new = 1, colnames = 3)
#> # A tibble: 6 x 4
#>    some   new colnames info.                
#>   <int> <int>    <int> <chr>                
#> 1     1     1        1 treatment vs. control
#> 2     1     1        2 treatment vs. control
#> 3     1     1        3 treatment vs. control
#> 4     2     1        1 treatment vs. control
#> 5     2     1        2 treatment vs. control
#> 6     2     1        3 treatment vs. control

reprex 包 (v0.3.0) 于 2021 年 8 月 26 日创建

Created on 2021-08-26 by the reprex package (v0.3.0)

更新

回答评论中添加的问题.是的,我们可以通过以下方式对上面的函数进行矢量化,这也允许在运行中跳过包含 0 的列:

To answer the added question in the comments. Yes we can vectorize the function above in the following way which also allows to skip columns in a run, when they contain a 0:

library(tidyverse)

foo <- function(...){
  
  dots <- rlang::list2(...) 
  var_nms <- names(dots)
  inp_ls <- map(dots, ~ map(.x, seq_len)) %>% transpose %>% map(compact)
  
  data_ls <- map(inp_ls, 
                 ~ tidyr::expand_grid(!!! .x,
                                      info. = c("control","treatment")))
  
  map2(data_ls, inp_ls, ~ .x %>% 
        dplyr::group_by(!!!syms(names(.y))) %>%
        dplyr::summarise(info. = stringr::str_c(sort(info., decreasing = TRUE), 
                                                collapse = ' vs. '), .groups = 'drop')) 
}

foo(some = c(1,2), new = c(1,0), colnames = c(1,3))
#> [[1]]
#> # A tibble: 1 x 4
#>    some   new colnames info.                
#>   <int> <int>    <int> <chr>                
#> 1     1     1        1 treatment vs. control
#> 
#> [[2]]
#> # A tibble: 6 x 3
#>    some colnames info.                
#>   <int>    <int> <chr>                
#> 1     1        1 treatment vs. control
#> 2     1        2 treatment vs. control
#> 3     1        3 treatment vs. control
#> 4     2        1 treatment vs. control
#> 5     2        2 treatment vs. control
#> 6     2        3 treatment vs. control

reprex 包 (v0.3.0) 于 2021 年 8 月 26 日创建

Created on 2021-08-26 by the reprex package (v0.3.0)

这篇关于通过 `...` 扩展 tidyverse 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆