r - 将两组列名传递给函数
问题描述
我正在尝试将两组列名传递给函数并使用 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))
解决方案
该vars()
功能可能非常适合这里。你会用它代替list()
你的函数参数。我在这个 SO 答案中看到了一个例子,它很容易扩展到你的情况。
在你的循环中加上一些 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()
(看起来我曾经学过,但后来忘记了:-D)。
推荐阅读
- python - 使用Python代码进行离散对数计算的问题
- java - 以正确的方式为我的用例实现 Oops 的正确设计模式
- azure - 运行命令扩展正在执行。请等待完成后再调用运行命令
- reactjs - 将背景颜色动态设置为 div 标签
- c# - 方法调用方法
- c# - 过滤、排序和分页实现太慢
- c++ - 如何检查 C++ 编译时是否存在特定的运算符重载?
- php - 我需要在 laravel 5.3 的视图文件夹中包含动态 js 和 css 文件所以我需要使用任何 Laravel url 函数来简单地指向文件
- c++ - MinGW GCC 通配符编译所有文件(Windows)
- javascript - 使用 p5.js 创建缩放效果