【问题标题】:Passing two sets of column names to function将两组列名传递给函数
【发布时间】:2019-06-14 20:22:51
【问题描述】:

我正在尝试将两组列名传递给函数并使用 dplyr 对它们进行处理。通常对于一组我会使用省略号 (...) 并使用 enquos() 将其转换为 quosures。但是现在我有两组列名,所以我考虑使用列表来存储它们。我应该如何以最有效的方式完成这项工作? (欢迎使用 purrr、rlang 和任何其他包的功能回答)

数据包和示例

library(dplyr) #I use whole library(tidyverse) but this is sufficient for this case

some.data <- tibble(col1 = sample(letters[1:3], 500, replace = T),
                    col2 = sample(letters[1:3], 500, replace = T),
                    col3 = sample(letters[4:6], 500, replace = T),
                    col4 = sample(letters[4:6], 500, replace = T))

我的函数(简单来说)如下所示:

cross_table <- function(data = NULL, list1 = NULL, list2 = NULL){

   for(l1 in list1){
      for(l2 in list2){

         data.out <- data %>% 
            count(l1, l2) %>% 
            spread(l2, n, fill = 0, drop = FALSE)

         print(data.out) #Just to show it works. I want to use 'data.out' object later on

      }
   }
}

我想使用这样的函数(不将列名作为字符串)

some.data %>%
   cross_table(list1 = list(col1, col2), list2 = list(col3, col4))

【问题讨论】:

    标签: r dplyr tidyeval


    【解决方案1】:

    vars() 函数可能非常适合这里。您可以在函数参数中使用它来代替 list()。我看到了一个例子in this SO answer,它很容易扩展到你的情况。

    在你的循环中加上一些 tidyeval 看起来像:

    cross_table <- function(data = NULL, list1 = NULL, list2 = NULL){
    
            for(l1 in list1){
                for(l2 in list2){
    
                    l1 = enquo(l1)
                    l2 = enquo(l2)
                    data.out <- data %>%
                        count(!!l1, !!l2) %>%
                        spread(!!l2, n, fill = 0, drop = FALSE) 
    
                    print(data.out) 
                }
            }
        }
    
    some.data %>%
       cross_table(list1 = vars(col1, col2), list2 = vars(col3, col4))
    
    
    # A tibble: 3 x 4
      col1      d     e     f
      <chr> <dbl> <dbl> <dbl>
    1 a        58    61    53
    2 b        38    59    47
    3 c        65    59    60
    # A tibble: 3 x 4
      col1      d     e     f
      <chr> <dbl> <dbl> <dbl>
    1 a        53    61    58
    2 b        44    47    53
    3 c        56    62    66
    # A tibble: 3 x 4
      col2      d     e     f
      <chr> <dbl> <dbl> <dbl>
    1 a        55    60    51
    2 b        57    67    56
    3 c        49    52    53
    # A tibble: 3 x 4
      col2      d     e     f
      <chr> <dbl> <dbl> <dbl>
    1 a        51    56    59
    2 b        63    55    62
    3 c        39    59    56
    

    您也可以使用alist() 代替list()(它看起来像I learned at one point,但后来忘记了:-D)。

    【讨论】:

    • 谢谢,现在可以了 :) 很高兴你也提醒了自己一些事情^^
    猜你喜欢
    • 2017-04-15
    • 2011-02-08
    • 1970-01-01
    相关资源
    最近更新 更多