【问题标题】:How do you calcuate mean values according to a factor while transferring the factor labels?在转移因子标签时如何根据因子计算平均值?
【发布时间】:2021-10-10 14:21:21
【问题描述】:

我得到了按行观察的数据。有一个结果变量 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 的平均值。这些应保存为 dat 中的因子,其中每个观测值都有一个 mean_f_1(数据根据 f_1 分组时的平均值)和 mean_f_2(数据根据 f_2 分组时的平均值)。新因子 mean_f_1 和 mean_f_2 的标签应对应于 f_1 和 f_2 的值 = 标签。标签是有意义的。因此,为组“A”(来自 f_1)计算的平均值应保留标签“A”(在 mean_f_1 中)。原始数据中条件变量 f_... 的数量大于 2。因此,我不想为每个因素重复代码(见 I)。

我想出了两种方法。第一个(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”语句似乎是可以避免的。我没有设法在这里使用cross()。

另一种方法(II; ave 方法)避免代码重复,但不会分配因子标签。使用 unique() 分配因子标签会打乱原始数据中标签的顺序。

II) 方法

dat %>% mutate(across(starts_with("f"), 
                      ~ ave(y, .x, FUN = mean),
                      .names = "mean_{.col}"))

你知道如何...

  • ...改进 (I) 以处理多个因素?
  • ...改进 (II) 以包含因子标签?
  • ...以不同的方式解决问题?

首选 dplyr 解决方案。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    为避免对每个因素重复代码,我建议对因素进行迭代。比如:

    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(.) 用于将字符串转换为列名。还有其他几种方法可以做到这一点,请参阅programming with dplyr 小插图了解其他选项。不寻常的赋值运算符:== 具有相同的行为,只是它可以接受左侧的一些准备。

    【讨论】:

    • 谢谢。我不知道“!!”称呼。它非常方便。最初,我希望避免循环因素,但我想这并不总是可能的。
    猜你喜欢
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多