r语言 - 计算频率表中数据的中位数



我想计算这个数据帧中每个组的年龄中位数:

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

注:我没有检查它如何处理频率计数中的非整数值,因为我认为您的原始数据很可能只包含整数频率计数。

最新更新