我正在尝试使用 tidyverse 创建一个函数,该函数允许我获取列名向量(类因子),计算有多少观察值满足特定条件(值 ==“是”),
mutate()
和使用此总和创建新列,以便稍后汇总数据。
我已经编写了一个可以为单个列执行此操作的函数,但我希望能够使用
all_of()
语法将任意长度的列名称向量传递给该函数。当我尝试这个时,我得到一个与向量同名的新列(包括我的_count
后缀)而不是向量中的值。
这类似于 TimTeaFan 的帖子 但我想传递一个长度 > 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"))))
或者如果你有一个长列表,那么你可以直接在
vars
语句中使用across
:
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