我想计算这个数据帧中每个组的年龄中位数:
dfx<-data.frame(group=c(1:100),
`1`=rnorm(100,50,0.5),
`2`=rnorm(100,45,15),
`3`=rnorm(100,17,5))
colnames(dfx) <- c("group", "1","2","3")
显示了不同组中年龄在1 - 3岁之间的个体数量(真实的数据框架有超过100列,从0 - 90+)。
# A tibble: 100 × 4
group `1` `2` `3`
<int> <dbl> <dbl> <dbl>
1 1 49.7 39.5 15.2
2 2 49.0 41.4 20.3
3 3 49.5 74.8 8.31
4 4 50.0 34.4 18.2
5 5 49.9 41.5 17.1
6 6 49.7 40.4 21.0
7 7 49.6 72.6 23.8
8 8 50.4 41.9 14.9
9 9 50.3 63.8 17.8
10 10 50.0 34.7 26.2
# … with 90 more rows
我想计算每个组的年龄中位数,得出如下结果:
dfxx<-data.frame(group=c(1:100),
med_age=rnorm(100,2,0.0001))
请注意,这些都是整数,就像原始年龄数据一样。
# A tibble: 100 × 2
group med_age
<int> <dbl>
1 1 2.00
2 2 2.00
3 3 2.00
4 4 2.00
5 5 2.00
6 6 2.00
7 7 2.00
8 8 2.00
9 9 2.00
10 10 2.00
# … with 90 more rows
我假设我需要在计算中位数之前从数据中制作一个矢量/直方图,但我不确定如何做到这一点。
提前感谢!
经过一番研究,我找到了一种方法来实现dplyr
。
首先,为了理解,我建议你读一章整理数据在R数据科学。
基本上,我以一种方式开始整理数据,即每个观察值都有自己的行,每个变量都有自己的列。因为"age"实际上是一个变量,年龄1-3只是它的表达式,我们希望像这样重新排列我们的数据集:
library(tidyverse)
dfx <- pivot_longer(dfx, cols = c(2:4), names_to = "age", values_to = "frequency")
dfx$age <- as.numeric(dfx$age)
之后,它看起来整洁多了:
> dfx
# A tibble: 300 × 3
group age frequency
<int> <dbl> <dbl>
1 1 1 50.1
2 1 2 39.0
3 1 3 18.0
4 2 1 49.4
5 2 2 32.3
6 2 3 16.5
7 3 1 50.1
8 3 2 57.2
9 3 3 22.0
10 4 1 50.5
# … with 290 more rows
下一步是计算每个组的年龄中位数。例如,为了得到第1组的中位数,我们需要在组列中值为1的所有观测值(=行)。我们可以用group_by
把它们按基团分组。
要计算中位数,就像你建议的那样,我们需要将频率表反向工程到原始数据。这是通过在矢量中打印年龄和频率状态一样多的次数来实现的。我们用rep
。它有两个实参:将被重复的vector,以及将被重复多少次。
您可以在R for data Science的数据转换章节中查找。rep的解决方案来自这篇文章。
代码看起来像这样简单:med <- dfx %>%
group_by(group) %>%
summarise(median_age = median(rep(age,frequency)))
结果是这样的:
> med
# A tibble: 100 × 2
group median_age
<int> <dbl>
1 1 2
2 2 2
3 3 2
4 4 2
5 5 1
6 6 2
7 7 2
8 8 2
9 9 1
10 10 1
# … with 90 more rows
注:我没有检查它如何处理频率计数中的非整数值,因为我认为您的原始数据很可能只包含整数频率计数。