r - 让 quosures 在地图调用中工作
问题描述
我正在努力让 quosures 在map
通话中工作。
一些玩具数据:
library(tidyverse)
df <- tibble(
g1 = letters[1:2] %>%
rep(each = 3),
g2 = letters[3:5] %>%
rep(times = 2),
y = runif(6)
)
我可以让这个函数工作,在enquo
我将它传递给之前我是一个变量group_by
:
sum1 <- function(df, g){
g <- enquo(g)
df %>%
group_by(!! g) %>%
summarize(
mu = y %>%
mean
)
}
调用这个函数
sum1(df, g2)
让我得到预期的结果。但是如果我想map
超过多个分组变量,(即g1
& g2
)
str_c("g", 1:2) %>%
map(
function(i)
sum1(df, i)
)
返回错误
Error in grouped_df_impl(data, unname(vars), drop) :
Column `i` is unknown
如何quosures
在map
通话中进行设置?
解决方案
我们可以使用group_by_at
它可以将字符串作为参数
library(tidyverse)
sum1 <- function(df, grps){
map(grps, ~
df %>%
group_by_at(.x) %>%
summarise(mu = mean(y))
)
}
sum1(df, str_c("g", 1:2))
#[[1]]
# A tibble: 2 x 2
# g1 mu
# <chr> <dbl>
#1 a 0.440
#2 b 0.469
#[[2]]
# A tibble: 3 x 2
# g2 mu
# <chr> <dbl>
#1 c 0.528
#2 d 0.592
#3 e 0.243
关于函数中带quosure的参数的使用,不清楚是单参数还是多参数
如果我们将字符串作为参数,请将其转换为符号 ( sym
),然后计算 ( !!
)
sum2 <- function(df, grps){
map(grps, ~
df %>%
group_by(!! rlang::sym(.x)) %>%
summarise(mu = mean(y))
)
}
sum2(df, str_c("g", 1:2))
#[[1]]
# A tibble: 2 x 2
# g1 mu
# <chr> <dbl>
#1 a 0.440
#2 b 0.469
#[[2]]
# A tibble: 3 x 2
# g2 mu
# <chr> <dbl>
#1 c 0.528
#2 d 0.592
#3 e 0.243
另一个可以通过多个组的方法是
sum3 <- function(df, ...){
gs <- enquos(...)
map(gs, ~
df %>%
group_by(!! .x) %>%
summarise(mu = mean(y)))
}
sum3(df, g1, g2)
#[[1]]
# A tibble: 2 x 2
# g1 mu
# <chr> <dbl>
#1 a 0.440
#2 b 0.469
#[[2]]
# A tibble: 3 x 2
# g2 mu
# <chr> <dbl>
#1 c 0.528
#2 d 0.592
#3 e 0.243
推荐阅读
- java - Moneta 1.3 ExchangeRateProvider.getExchangeRate(base, term) 返回 null
- javascript - 使用 javascript 库进行图像处理
- reactjs - 将 forwardRef 与 Link 组件一起使用
- android - 安装失败并显示消息 Failed to finalize session : INSTALL_FAILED_DEXOPT:
- php - 如何将 Laravel 4.0 制作的项目迁移到 Laravel 5.2?
- ios - 如何防止谓词获取关系对象?
- c - c 中字符串首字母的大写 - 用 110 个字符编写 myprintf 函数
- liquibase - 如何在不提供 url、用户名、密码和驱动程序等数据库详细信息的情况下使用 Liquibase 创建脚本?
- c# - 使用 AndroidManagement API 在托管设备上安装应用程序的策略正文
- jpa - 如何在 kotlin/多平台项目中使用 JPA 注释?