是的,这是可能的。我们可以用省略号 ... 替换您的参数,并允许该函数生成任意数量的具有自定义列名的列。这是 tidyverse 风格的这样一个函数:
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 package (v0.3.0) 于 2021 年 8 月 26 日创建
更新
回答 cmets 中添加的问题。是的,我们可以通过以下方式对上面的函数进行矢量化,这也允许在运行中跳过包含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 package (v0.3.0) 于 2021 年 8 月 26 日创建