R dplyr:独立计算每个因素的因素内差异

R dplyr:独立计算每个因素的因素内差异,r,dplyr,R,Dplyr,备选标题:对于每个组,分别计算其子组之间的差异 我试图计算,对于多个独立的因素,一个水平与给定因素内所有其他水平的平均值的差值。换句话说:如果我有3组的年龄,我想计算第1组的得分与其他2组的平均值的差异,以此类推 结果会给人一个印象,群体之间的相对表现,我将绘制结果。使用总体平均值不是一种选择,因为如果18-30岁年龄组占样本的80%,那么结果会有偏差,总体平均值将由这一组主导 下面是一个可复制的示例,以及我迄今为止的代码: library(dplyr) set.seed(123) # Da

备选标题:对于每个组,分别计算其子组之间的差异

我试图计算,对于多个独立的因素,一个水平与给定因素内所有其他水平的平均值的差值。换句话说:如果我有3组的年龄,我想计算第1组的得分与其他2组的平均值的差异,以此类推

结果会给人一个印象,群体之间的相对表现,我将绘制结果。使用总体平均值不是一种选择,因为如果18-30岁年龄组占样本的80%,那么结果会有偏差,总体平均值将由这一组主导

下面是一个可复制的示例,以及我迄今为止的代码:

library(dplyr)

set.seed(123)

# Data
df <- data.frame(score = sample(0:10, 20, replace=T), 
                 sex = sample(c("male","female"), 20, replace=T), 
                 age = sample(c("18-30","31-50","51-70"), 20, replace=T))

# Make data long
df_long <-
  df %>% 
    pivot_longer(-score, names_to = "factor", values_to = "level")

# Calculate level means
df_means <- 
  df_long %>%
    group_by_at(vars(factor, level)) %>% 
    summarise_all(mean, na.rm=T)

# Calculate within-factor differences, for each level
# ??
我似乎不知道如何最好地使用group_by和Summary来计算每个因素之间的差异?非常感谢任何指点

PS.接近,但仅当系数中只有两个级别时才有效。

基本R解决方案:

# Mean of each age: mean_df => data.frame
mean_df <- data.frame(lapply(split(df, df$age), 
            function(x){mean(x$score, na.rm = TRUE)}))

# Difference each mean in the group: mean_diff => list
mean_diff <- sapply(mean_df, `-`, mean_df)

# Add row.names as a vector: mean_diff_df => data.frame
mean_diff_df <- data.frame(cbind(vars = rownames(mean_diff), mean_diff), row.names = NULL)

你在找这样的东西吗

# Calculate the overall mean:
df_new = df %>% mutate(m_score = mean(score))

# Separately calculate the mean for both factors, create pivot and then add them together:
df_new %>% 
  group_by(sex) %>% 
  summarise(mean_level_score = mean(score),
            score_diff = mean_level_score - mean(m_score)) %>% 
  pivot_longer(-c("score_diff", "mean_level_score"), names_to = "factor", values_to = "level") %>% 
  bind_rows(df_new %>%
            group_by(age) %>%
            summarise(mean_level_score = mean(score),
                      score_diff = mean_level_score - mean(m_score)) %>%
            pivot_longer(-c("score_diff", "mean_level_score"), names_to = "factor", values_to = "level"))
请注意,分数_diff现在是通过使用总体平均值计算的,但不作为1个级别与给定因子内所有其他级别平均值的差值。我无法想象在任何情况下,只使用其他因素的水平可能有用

输出如下所示:

# A tibble: 5 x 3
# Groups:   factor [2]
  factor level  score
  <chr>  <fct>  <dbl>
1 age    18-30   5.67
2 age    31-50   6.43
3 age    51-70   3.75
4 sex    female  5.92
5 sex    male    4.86
# A tibble: 5 x 4
  mean_level_score score_diff factor level 
             <dbl>      <dbl> <chr>  <chr> 
1             5.43      0.379 sex    female
2             4.85     -0.204 sex    male  
3             5.17      0.117 age    18-30 
4             4.57     -0.479 age    31-50 
5             5.43      0.379 age    51-70 
女性的得分差异为0.379意味着她们的平均得分5.43比整个人群的平均得分5.05高出0.379。同样,31-50岁的人平均得分为-0.479,低于5.05的平均分

很抱歉代码太长,我想这可以做得更优雅…

我们可以按因子分组,并使用map\u dbl计算组内平均值

library(dplyr)

df_means %>%
  group_by(factor) %>%
  mutate(diff = purrr::map_dbl(seq_along(score), ~score[.x] - mean(score[-.x])))

使用总体平均值的好方法,尽管事实上我希望在因子内进行计算。一般来说,使用总体平均值会导致统计数据的偏差:例如,如果18-30岁年龄组占样本的90%,那么90%的总体平均值来自18-30岁-在这种情况下,将18-30岁的平均值与总体平均值进行比较就像将18-30岁的平均值与自身进行比较…嗯,好的。对不起,这没用。我在想一个解决方案,但你得做很多计算,对吗?我的意思是,每个因子最多有3个级别,这应该没问题。但是,您始终需要对每个级别平均值和相应的非级别平均值进行两次计算。如果这是一个适用的统计方法,我可以想象有人已经把它做成了一个包?!也许你可以研究一下这个问题,而不是用手去做?看看@RonakShah的解决方案,这是一种享受。感谢您花时间尝试并找到解决方案!感谢这段代码,尽管最终结果是一个差异矩阵,而不是一列差异。正如我在问题的末尾所展示的,我们的想法是在每个因素中单独列出一组与所有其他组的平均值之间的差异?你的年龄只有3组。您能否将样本数据增加到3组以上,并显示输出结果。另外,如果您在生成数据以实现再现性时使用set.seed也会更好。谢谢@RonakShah,刚刚编辑。年龄组的确切数量并不重要,更重要的是,当一个给定因子中有两个以上的组时,如何计算这个问题。当然,如何独立地计算每个因素!提前感谢您的帮助,我不知道您是如何使用分数值获得所显示的差异值的。你能解释一下你是如何得到年龄的0.58,1.72和-2.30的吗?我取1组的值,减去其他组的平均值,例如,18-30我得到5.67-意味着6.43,3.75难以置信,这太完美了!谢谢:
library(dplyr)

df_means %>%
  group_by(factor) %>%
  mutate(diff = purrr::map_dbl(seq_along(score), ~score[.x] - mean(score[-.x])))