问题描述
我需要通过 3 个变量(性别、部门和职业)计算加权平均年龄。我知道如何使用“spatstat”weighted.median。但它给出了整个 DF 的加权年龄。我不知道让它按组/变量计算很热。我发现了 2 年前的另一个类似帖子,但我不明白其中提供的解决方案。我确实知道您需要使用 dplyr 对其进行分组。我对图书馆的了解非常有限。我需要有人向我展示以下 DF 的代码,以便我可以使用它并在将来需要时对其进行小的更改。
我的DF是这样的:原来的df要大得多,部门和职业也多得多。但是结构是一样的。
Gender Sector occupation Age Weight M A 1 45 13.12 F C 1 23 7.05 M A 3 67 34.12 M A 3 23 11.00 F C 1 33 17.45 F A 1 35 45.01 F C 3 57 21.45 M C 1 32 23.33 F A 3 48 44.54 M A 1 25 13.12 F C 1 27 7.05 M A 3 37 34.12 M A 3 26 11.00 F C 1 73 17.45 F A 1 49 45.01 F C 3 24 21.45 M C 1 25 23.33 F A 3 35 44.54 M A 1 48 13.12 F C 1 83 7.05 M A 3 66 34.12 M A 3 43 11.00 F C 1 36 17.45 F A 1 35 45.01 F C 3 57 21.45 M C 1 22 23.33 F A 3 47 44.54 M A 1 55 13.12 F C 1 28 7.05 M A 3 27 34.12 M A 3 25 11.00 F C 1 23 17.45 F A 1 46 45.01 F C 3 34 21.45 M C 1 27 23.33 F A 3 65 44.54
这就是我需要的结果。注意!这里的年龄中位数是假的。它只是代表最终结果的结构。
Gender Sector occupation Median age M A 1 23 M A 3 34 M C 1 45 M C 3 23 F A 1 34 F A 3 45 F C 1 43 F C 3 34
我发现的问题(上面提到的)我不明白,因为我不明白 mutate 并且示例中的数据以我无法阅读的方式呈现。我是 R 的新手
解决方法
weighted.median
包中有一个 spatstat
。我们可以将其与 tidyverse
方法一起使用,即按“性别”、“部门”和“职业”分组,将 weighted.median
与 x
应用为“年龄”和 w
作为 summarise
中的“重量”。
在链接的帖子中,它使用 mutate
创建一个新列,而 summarise
返回汇总输出,即每组一行。
此外,我们在使用 summarise/mutate
时应该小心,因为这些函数也可以在 plyr
中找到,如果两个包都被加载,它可能会屏蔽 dplyr
函数,即如果被屏蔽使用了 plyr
中的函数,然后它可能会返回整个数据的 weighted.median
而不是分组。因此,要么只加载 dplyr
,要么显式使用 dplyr::summarise
library(dplyr)
library(spatstat)
df1 %>%
group_by(Gender,Sector,occupation) %>%
dplyr::summarise(MedianAge = weighted.median(Age,Weight),.groups = 'drop')
-输出
# A tibble: 7 x 4
Gender Sector occupation MedianAge
<chr> <chr> <int> <dbl>
1 F A 1 35
2 F A 3 47
3 F C 1 31.0
4 F C 3 34
5 M A 1 45
6 M A 3 33.8
7 M C 1 25
数据
df1 <- structure(list(Gender = c("M","F","M","F"),Sector = c("A","C","A","A"),occupation = c(1L,1L,3L,3L),Age = c(45L,23L,67L,33L,35L,57L,32L,48L,25L,27L,37L,26L,73L,49L,24L,83L,66L,43L,36L,22L,47L,55L,28L,46L,34L,65L),Weight = c(13.12,7.05,34.12,11,17.45,45.01,21.45,23.33,44.54,13.12,44.54)),class = "data.frame",row.names = c(NA,-36L))