purrr:将列名作为参数列表交给 pmap()

purrr: Hand over column names as parameter list to pmap()

我想使用 purr::pmap() 将列名作为参数传递给在 dplyr 函数中使用这些名称的函数。示例:

library(purrr)
library(dplyr)

tib <- tibble(A1 = 0:9, A2 = 10:19, A3 = 20:29, 
              B1 = 30:39, B2 = 40:49, B3 = 50:59,
              C1 = 60:69, C2 = 70:79, C3 = 80:89)

select_three <- function(data, first, second, third) {
  
  result = data %>% 
    select({{first}}, {{second}}, {{third}})
  
  result
}

这个有效:

single_test <- select_three(tib, A1, A2, A3)
print(single_test)
# A tibble: 10 x 3
      A1    A2    A3
   <int> <int> <int>
 1     0    10    20
 2     1    11    21
 3     2    12    22
 4     3    13    23
 5     4    14    24
 6     5    15    25
 7     6    16    26
 8     7    17    27
 9     8    18    28
10     9    19    29

这不是:

params <- list(tib,
               c(A1, B1, C1),
               c(A2, B2, C2),
               c(A3, B3, C3))

pmap_test <- pmap_dfr(params, select_three)

Error: Element 1 of `.l` must have length 1 or 30, not 9

我建议改为传递字符向量。

library(purrr)
library(dplyr)

params <- list(c("A1", "B1", "C1"),
              c("A2", "B2", "C2"),
              c("A3", "B3", "C3"))

select_three <- function(data, first, second, third) {
  result = data %>% select(.data[[first]], .data[[second]], .data[[third]])
  result
}


pmap(params, ~select_three(tib, ..1, ..2, ..3))

请注意 select 与字符参数一起使用,因此使用 data %>% select(first, second, third) 可以在这里工作,但如果您打算将其用于 select 以外的其他用途,一般方法是使用.data 代词。

使用

params <- list(tib,
               c("A1", "B1", "C1"),
               c("A2", "B2", "C2"),
               c("A3", "B3", "C3"))

pmap_test <- pmap(.l = params[2:4], select_three, data = tib)

[[1]]
# A tibble: 10 x 3
      A1    A2    A3
   <int> <int> <int>
 1     0    10    20
 2     1    11    21
 3     2    12    22
 4     3    13    23
 5     4    14    24
 6     5    15    25
 7     6    16    26
 8     7    17    27
 9     8    18    28
10     9    19    29

[[2]]
# A tibble: 10 x 3
      B1    B2    B3
   <int> <int> <int>
 1    30    40    50
 2    31    41    51
 3    32    42    52
 4    33    43    53
 5    34    44    54
 6    35    45    55
 7    36    46    56
 8    37    47    57
 9    38    48    58
10    39    49    59

[[3]]
# A tibble: 10 x 3
      C1    C2    C3
   <int> <int> <int>
 1    60    70    80
 2    61    71    81
 3    62    72    82
 4    63    73    83
 5    64    74    84
 6    65    75    85
 7    66    76    86
 8    67    77    87
 9    68    78    88
10    69    79    89