计算人口年龄四分位数范围并将结果存储为 R 中的数据框的最佳方法
Best way to calculate quartile ranges of population ages and store results as a data frame in R
我有一个数据框,其中包含多年来每年的人口数据。我想获得每年的中位数、Q1 和 Q3 年龄,并将结果存储为新的数据框。解决这个问题的最佳方法是什么?这是我的数据示例。每一年列包含相应年龄的人数:
Age | 2000 | 2001 | 2002
------------------------
2 | 4 | 1 | 2
3 | 6 | 3 | 5
4 | 10 | 9 | 8
5 | 8 | 9 | 8
6 | 7 | 7 | 8
编辑:只是为了添加更多细节。要获得中位数和四分位数范围,我很可能需要获得每年的累积频率。我可以创建一个包含所有 CF 的数据框并加入年龄列,并基于此创建一个具有中位数和 q 范围年龄的新数据框,但我相信有一种更有效的方法可以做到这一点。
好的,根据您的描述,我更新了我的代码。首先,我每年递增年龄分布,然后计算所需的统计数据:
library(dplyr)
library(tidyr)
df <- tribble(
~ Age, ~`2000`, ~`2001`, ~`2002`,
2, 4, 1, 2,
3, 6, 3, 5,
4, 10, 9, 8,
5, 8, 9, 8,
6, 7, 7, 8
)
df %>%
rowwise() %>%
mutate(across(`2000`:`2002`, ~ list(rep(Age, .x)))) %>%
pivot_longer(- Age, names_to = "years", values_to = "values") %>%
unnest(values) %>%
select(-Age) %>%
group_by(years) %>%
summarise(medians = median(values),
quantiles = list(quantile(values, probs = c(0.25, 0.75)))) %>%
unnest_wider(quantiles)
# A tibble: 3 x 4
years medians `25%` `75%`
<chr> <dbl> <dbl> <dbl>
1 2000 4 3 5
2 2001 5 4 5
3 2002 5 4 5.5
如果您需要进一步的解释,请告诉我。
有一个非常有用的函数 uncount
in the tidyr
package that we can use. First, we use pivot_longer
可以将年份列移动为行。然后,我们使用 uncount
以便每个年龄出现的次数与它出现的次数一样多。然后,group_by
年并使用 summarise
.
计算汇总统计数据
library(tidyverse)
dat %>%
pivot_longer(-Age,
names_to = "year",
names_prefix = "X",
values_to = "cnt") %>%
uncount(cnt) %>%
group_by(year) %>%
summarise(q25 = quantile(Age, .25),
q50 = median(Age),
q75 = quantile(Age, .75))
# year q25 q50 q75
# <chr> <dbl> <int> <dbl>
# 1 2000 3 4 5
# 2 2001 4 5 5
# 3 2002 4 5 5.5
这是一个基本的 R 解决方案,使用与 rep
函数类似的想法:
apply(dat[,-1], 2,
FUN = function(x){
rep_age <- rep(dat$Age, x)
c(quantile(rep_age, .25),
quantile(rep_age, .5),
quantile(rep_age, .75))
})
# X2000 X2001 X2002
# 25% 3 4 4.0
# 50% 4 5 5.0
# 75% 5 5 5.5
数据
dat <- structure(list(Age = 2:6,
X2000 = c(4L, 6L, 10L, 8L, 7L),
X2001 = c(1L, 3L, 9L, 9L, 7L),
X2002 = c(2L, 5L, 8L, 8L, 8L)),
class = "data.frame",
row.names = c(NA, -5L))
我有一个数据框,其中包含多年来每年的人口数据。我想获得每年的中位数、Q1 和 Q3 年龄,并将结果存储为新的数据框。解决这个问题的最佳方法是什么?这是我的数据示例。每一年列包含相应年龄的人数:
Age | 2000 | 2001 | 2002
------------------------
2 | 4 | 1 | 2
3 | 6 | 3 | 5
4 | 10 | 9 | 8
5 | 8 | 9 | 8
6 | 7 | 7 | 8
编辑:只是为了添加更多细节。要获得中位数和四分位数范围,我很可能需要获得每年的累积频率。我可以创建一个包含所有 CF 的数据框并加入年龄列,并基于此创建一个具有中位数和 q 范围年龄的新数据框,但我相信有一种更有效的方法可以做到这一点。
好的,根据您的描述,我更新了我的代码。首先,我每年递增年龄分布,然后计算所需的统计数据:
library(dplyr)
library(tidyr)
df <- tribble(
~ Age, ~`2000`, ~`2001`, ~`2002`,
2, 4, 1, 2,
3, 6, 3, 5,
4, 10, 9, 8,
5, 8, 9, 8,
6, 7, 7, 8
)
df %>%
rowwise() %>%
mutate(across(`2000`:`2002`, ~ list(rep(Age, .x)))) %>%
pivot_longer(- Age, names_to = "years", values_to = "values") %>%
unnest(values) %>%
select(-Age) %>%
group_by(years) %>%
summarise(medians = median(values),
quantiles = list(quantile(values, probs = c(0.25, 0.75)))) %>%
unnest_wider(quantiles)
# A tibble: 3 x 4
years medians `25%` `75%`
<chr> <dbl> <dbl> <dbl>
1 2000 4 3 5
2 2001 5 4 5
3 2002 5 4 5.5
如果您需要进一步的解释,请告诉我。
有一个非常有用的函数 uncount
in the tidyr
package that we can use. First, we use pivot_longer
可以将年份列移动为行。然后,我们使用 uncount
以便每个年龄出现的次数与它出现的次数一样多。然后,group_by
年并使用 summarise
.
library(tidyverse)
dat %>%
pivot_longer(-Age,
names_to = "year",
names_prefix = "X",
values_to = "cnt") %>%
uncount(cnt) %>%
group_by(year) %>%
summarise(q25 = quantile(Age, .25),
q50 = median(Age),
q75 = quantile(Age, .75))
# year q25 q50 q75
# <chr> <dbl> <int> <dbl>
# 1 2000 3 4 5
# 2 2001 4 5 5
# 3 2002 4 5 5.5
这是一个基本的 R 解决方案,使用与 rep
函数类似的想法:
apply(dat[,-1], 2,
FUN = function(x){
rep_age <- rep(dat$Age, x)
c(quantile(rep_age, .25),
quantile(rep_age, .5),
quantile(rep_age, .75))
})
# X2000 X2001 X2002
# 25% 3 4 4.0
# 50% 4 5 5.0
# 75% 5 5 5.5
数据
dat <- structure(list(Age = 2:6,
X2000 = c(4L, 6L, 10L, 8L, 7L),
X2001 = c(1L, 3L, 9L, 9L, 7L),
X2002 = c(2L, 5L, 8L, 8L, 8L)),
class = "data.frame",
row.names = c(NA, -5L))