在自定义 dplyr 函数中使用列向量
Use vector of columns in custom dplyr function
我正在尝试使用 tidyverse 创建一个函数,该函数允许我获取列名向量(class 因子),计算有多少观察值满足特定条件(值 ==“ yes"), mutate()
并使用此总和创建新列,以便稍后汇总数据。
我已经编写了一个可以对单个列执行此操作的函数,但我希望能够使用 all_of()
语法将任意长度的列名向量传递给该函数。当我尝试这个时,我得到一个与向量同名的新列(包括我的 _count
后缀)而不是向量中的值。
这与 类似,但我想传递一个长度 > 1 的向量。
我想我可能需要使用 dplyr 中的 (. . .) 选项和一些更多的 rlang,但我还没有找到正确的组合。由于 NSE,当我用 (...) 代替 objective 时,该功能不起作用。我还尝试了 rlang::as_name()
和 rlang::get_env()
的变体。有一个过时的工作簿也使用了 purrr::map()
,但我没有运气在这里实施它。
我得到错误:找不到列 x
。
或错误:Promise 已被强制
这是一个带有数据的可重现示例
dat <- tibble(category = rep(letters[1:10], 2),
intake = factor(c(rep("no", 12), rep("yes", 8))),
outtake = factor(c(rep("yes", 11), rep("no", 9))),
pretake = factor(c(rep(c("no", "yes"), 10))))
yessum <- function(.data, objective) {
.data %>%
dplyr::mutate("{{objective}}_count" := sum(
ifelse(
unlist(!!rlang::ensym(objective)) == "yes", 1, 0)))
}
dat %>%
group_by(category) %>%
yessum(intake)
我希望能够将某些列名的向量传递给 yessum 并接收一组新列,就像 intake_new
但命名为 outtake_new
和 pretake_new
.
这是我尝试时目前发生的情况:
vars <- c("intake", "outtake", "pretake")
dat %>%
group_by(category) %>%
yessum(vars)
欢迎任何帮助!
您不一定需要该函数,因为您可以只 mutate
across
列并获取每个类别的总和。
library(tidyverse)
dat %>%
group_by(category) %>%
mutate(across(ends_with("take"), .fns = list(count = ~sum(. == "yes"))))
或者如果你有一个长列表,那么你可以在across
语句中直接使用vars
:
vars <- c("intake", "outtake", "pretake")
dat %>%
group_by(category) %>%
mutate(across(vars, .fns = list(count = ~sum(. == "yes"))))
输出
category intake outtake pretake intake_count outtake_count pretake_count
<chr> <fct> <fct> <fct> <int> <int> <int>
1 a no yes no 0 2 0
2 b no yes yes 0 1 2
3 c no yes no 1 1 0
4 d no yes yes 1 1 2
5 e no yes no 1 1 0
6 f no yes yes 1 1 2
7 g no yes no 1 1 0
8 h no yes yes 1 1 2
9 i no yes no 1 1 0
10 j no yes yes 1 1 2
11 a no yes no 0 2 0
12 b no no yes 0 1 2
13 c yes no no 1 1 0
14 d yes no yes 1 1 2
15 e yes no no 1 1 0
16 f yes no yes 1 1 2
17 g yes no no 1 1 0
18 h yes no yes 1 1 2
19 i yes no no 1 1 0
20 j yes no yes 1 1 2
我正在尝试使用 tidyverse 创建一个函数,该函数允许我获取列名向量(class 因子),计算有多少观察值满足特定条件(值 ==“ yes"), mutate()
并使用此总和创建新列,以便稍后汇总数据。
我已经编写了一个可以对单个列执行此操作的函数,但我希望能够使用 all_of()
语法将任意长度的列名向量传递给该函数。当我尝试这个时,我得到一个与向量同名的新列(包括我的 _count
后缀)而不是向量中的值。
这与
我想我可能需要使用 dplyr 中的 (. . .) 选项和一些更多的 rlang,但我还没有找到正确的组合。由于 NSE,当我用 (...) 代替 objective 时,该功能不起作用。我还尝试了 rlang::as_name()
和 rlang::get_env()
的变体。有一个过时的工作簿也使用了 purrr::map()
,但我没有运气在这里实施它。
我得到错误:找不到列 x
。
或错误:Promise 已被强制
这是一个带有数据的可重现示例
dat <- tibble(category = rep(letters[1:10], 2),
intake = factor(c(rep("no", 12), rep("yes", 8))),
outtake = factor(c(rep("yes", 11), rep("no", 9))),
pretake = factor(c(rep(c("no", "yes"), 10))))
yessum <- function(.data, objective) {
.data %>%
dplyr::mutate("{{objective}}_count" := sum(
ifelse(
unlist(!!rlang::ensym(objective)) == "yes", 1, 0)))
}
dat %>%
group_by(category) %>%
yessum(intake)
我希望能够将某些列名的向量传递给 yessum 并接收一组新列,就像 intake_new
但命名为 outtake_new
和 pretake_new
.
这是我尝试时目前发生的情况:
vars <- c("intake", "outtake", "pretake")
dat %>%
group_by(category) %>%
yessum(vars)
欢迎任何帮助!
您不一定需要该函数,因为您可以只 mutate
across
列并获取每个类别的总和。
library(tidyverse)
dat %>%
group_by(category) %>%
mutate(across(ends_with("take"), .fns = list(count = ~sum(. == "yes"))))
或者如果你有一个长列表,那么你可以在across
语句中直接使用vars
:
vars <- c("intake", "outtake", "pretake")
dat %>%
group_by(category) %>%
mutate(across(vars, .fns = list(count = ~sum(. == "yes"))))
输出
category intake outtake pretake intake_count outtake_count pretake_count
<chr> <fct> <fct> <fct> <int> <int> <int>
1 a no yes no 0 2 0
2 b no yes yes 0 1 2
3 c no yes no 1 1 0
4 d no yes yes 1 1 2
5 e no yes no 1 1 0
6 f no yes yes 1 1 2
7 g no yes no 1 1 0
8 h no yes yes 1 1 2
9 i no yes no 1 1 0
10 j no yes yes 1 1 2
11 a no yes no 0 2 0
12 b no no yes 0 1 2
13 c yes no no 1 1 0
14 d yes no yes 1 1 2
15 e yes no no 1 1 0
16 f yes no yes 1 1 2
17 g yes no no 1 1 0
18 h yes no yes 1 1 2
19 i yes no no 1 1 0
20 j yes no yes 1 1 2