我已经得到了行观察数据。有一个结果变量y (dbl)以及多个因素,这里称为f_1和f_2。后者表示实验的条件。下面的最小示例反映了数据情况:
set.seed(123)
y = rnorm(10)
f_1 = factor(rep(c("A", "B"), 5))
f_2 = factor(rep(c("C", "D"), each = 5))
dat <- data.frame(y, f_1, f_2)
我想计算由f_1和f_2定义的群的y的平均值。重要的是,我不想要f_1和f_2的每个组合的平均值,但一方面是基于f_1的平均值,另一方面是基于f_2的平均值。这些应该作为数据中的因素保存,其中每个观测值都有一个mean_f_1(数据按f_1分组时的平均值)和mean_f_2(数据按f_2分组时的平均值)。新因子mean_f_1和mean_f_2的标签对应于f_1和f_2的值=标签。标签是有含义的。因此,计算出a组的平均值;(from f_1)应保留标签";a &;"(在mean_f_1)。条件变量f_…在原始数据中大于2。因此,我不想为每个因素重复代码(见1)。
我想到了两种方法。第一个(I;Group_by方法)给出了期望的结果。但是对每个因子都重复代码。
I) group_by方法library(dplyr)
dat %>%
group_by(f_1) %>%
mutate(mean_f_1 = factor(mean(y), label = unique(f_1))) %>%
group_by(f_2) %>%
mutate(mean_f_2 = factor(mean(y), label = unique(f_2)))
换句话说,为每个因素重复'group_by - mutate'语句似乎是可以避免的。我没有设法在这里使用across()。
另一种方法(II;Ave方法)避免代码重复,但不分配因子标签。使用unique()赋值因子标签会打乱原始数据中标签的顺序。
dat %>% mutate(across(starts_with("f"),
~ ave(y, .x, FUN = mean),
.names = "mean_{.col}"))
你知道如何……吗?
- …改进(1)以处理多因素?
- …改进(II)以包括因素标签?
- …以不同的方式解决问题?
首选dplyr方案。
为了避免对每个因素重复编写代码,我建议对每个因素进行迭代。比如:
library(dplyr)
factors = c("f_1", "f_2")
for(ff in factors){
new_col = paste0("mean_",ff)
dat <- dat %>%
group_by(!!sym(ff)) %>%
mutate(!!sym(new_col) := factor(mean(y), label = unique(!!sym(ff))))
}
这与您的group_by
方法产生相同的输出。要扩展到更多列,请将这些列添加到factors
数组中,代码将遍历它们。
!!sym(.)
用于将字符串转换为列名。还有其他几种方法可以做到这一点,请参阅使用dplyr vignette进行编程以了解其他选项。不寻常的赋值运算符:=
与=
的行为相同,只是它可以在左侧接受一些预处理。