绘制具有已知错误的时间序列 (ggplot2)
Plot time series with known error (ggplot2)
我正在使用美国社区调查 (ACS) 对特定地点未来几年的 1 年估计。例如,我正在尝试绘制骑自行车上班的男性和女性比例随时间的变化情况。从 ACS 中,我得到估计值和标准误差,然后我可以用它来计算估计值的上限和下限。
所以宽格式的简化数据结构是这样的:
| Year | EstimateM | MaxM | MinM | EstimateF | MaxF | MinF |
|------|-----------|------|------|-----------|------|------|
| 2005 | 3.0 | 3.5 | 2.5 | 2.0 | 2.3 | 1.7 |
| 2006 | 3.1 | 3.5 | 2.6 | 2.0 | 2.3 | 1.7 |
| 2007 | 5.0 | 4.2 | 5.8 | 2.5 | 3.0 | 2.0 |
| ... | ... | ... | ... | ... | ... | ... |
如果我只想绘制估计值,我会 melt
只有两个 Estimate
变量的数据 measure.vars
GenderModeCombined_long <- melt(GenderModeCombined,
id = "Year",
measure.vars = c("EstimateM",
"EstimateF")
然后可以使用 ggplot2
轻松绘制长数据
ggplot(data=GenderModeCombined_long,
aes(x=year, y=value, colour=variable)) +
geom_point() +
geom_line()
这会生成这样的图表
(抱歉,post 图片没有足够的代表)
我卡住的地方是如何将误差线添加到两个估计图。我可以将它们作为 measure vars
添加到融化的数据集中,但是我如何告诉 ggplot 应该将什么绘制为值以及将什么绘制为误差线?我是否必须只使用 min/max 数据创建一个单独的数据框,然后单独加载它?
geom_errorbar(data = errordataMmax, aes(ymax = ??, ymin = ??))
我感觉我处理这个问题的方式不对and/or 我的数据设置有误。
欢迎来到 SO。这里的问题是你有三个 "explicit" 变量(估计,
Min 和 Max)和一个 "implicit" 一个(性别),它在列名中编码。解决此问题的一种方法是使 "gender" 成为显式分组变量。转到长格式后,创建一个 "gender" 变量,从键列(变量)中删除性别指示,然后返回宽格式。
像这样的东西会起作用:
library(ggplot2)
library(dplyr)
library(tidyr)
library(tibble)
GenderModeCombined <- tibble::tribble(
~Year, ~EstimateM, ~MaxM, ~MinM, ~EstimateF, ~MaxF, ~MinF,
2005, 3.0, 3.5, 2.5, 2.0, 2.3, 1.7,
2006, 3.1, 3.5, 2.6, 2.0, 2.3, 1.7,
2007, 5.0, 4.2, 5.8, 2.5, 3.0, 2.0
)
GenderModeCombined.long <- GenderModeCombined %>%
# switch to long format
tidyr::gather(variable, value, -Year, factor_key = TRUE) %>%
# add a gender variable
dplyr::mutate(gender = stringr::str_sub(variable, -1)) %>%
# remove gender indication from the key column `variable`
dplyr::mutate(variable = stringr::str_sub(variable, end = -2)) %>%
# back to wide format
tidyr::spread(variable, value)
GenderModeCombined.long
#> # A tibble: 6 x 5
#> Year gender Estimate Max Min
#> <dbl> <chr> <dbl> <dbl> <dbl>
#> 1 2005 F 2 2.3 1.7
#> 2 2005 M 3 3.5 2.5
#> 3 2006 F 2 2.3 1.7
#> 4 2006 M 3.1 3.5 2.6
#> 5 2007 F 2.5 3 2
#> 6 2007 M 5 4.2 5.8
ggplot(data=GenderModeCombined.long,
aes(x=Year, y=Estimate,colour = gender)) +
geom_point() +
geom_line() +
geom_errorbar(aes(ymax = Max, ymin = Min))
由 reprex package (v0.2.1)
创建于 2018-12-29
正如 所解释的那样,这个问题的答案与其说是关于绘图,不如说是关于将数据从宽格式重塑为长格式。这里的挑战是每个性别都有多个值列,即 Estimate
、Max
、Min
。
从版本 v1.9.6(2015 年 9 月 19 日在 CRAN 上)开始,data.table 的 melt()
函数的化身允许熔化,即从宽格式重塑为长格式,变成多个一口气列:
library(data.table)
options(datatable.print.class = TRUE)
cols <- c("Estimate", "Max", "Min")
long <- melt(setDT(GenderModeCombined), id.vars = "Year", measure.vars = patterns(cols),
value.name = cols, variable.name = "Gender")[
, Gender := forcats::lvls_revalue(Gender, c("M", "F"))][]
long
Year Gender Estimate Max Min
<int> <fctr> <num> <num> <num>
1: 2005 M 3.0 3.5 2.5
2: 2006 M 3.1 3.5 2.6
3: 2007 M 5.0 4.2 5.8
4: 2005 F 2.0 2.3 1.7
5: 2006 F 2.0 2.3 1.7
6: 2007 F 2.5 3.0 2.0
现在,我们可以根据需要绘制每个 Year
和 Gender
的三个观察结果:
library(ggplot2)
ggplot(long, aes(x = Year, y = Estimate, colour = Gender)) +
geom_point() +
geom_line() +
geom_errorbar(aes(ymax = Max, ymin = Min), width = 0.1)
请注意,除了点和误差条之外,此图表还显示线条。这是因为 Year
是 整数 类型,ggplot2
将其识别为连续变量。
数据
data.table的fread()
函数读取各种数据格式非常得心应手。因此,我们只需稍作修改即可读取 OP 发布的数据:
library(data.table)
GenderModeCombined <- fread(
"| Year | EstimateM | MaxM | MinM | EstimateF | MaxF | MinF |
| 2005 | 3.0 | 3.5 | 2.5 | 2.0 | 2.3 | 1.7 |
| 2006 | 3.1 | 3.5 | 2.6 | 2.0 | 2.3 | 1.7 |
| 2007 | 5.0 | 4.2 | 5.8 | 2.5 | 3.0 | 2.0 |
", drop = c(1L, 9L))
GenderModeCombined
Year EstimateM MaxM MinM EstimateF MaxF MinF
<int> <num> <num> <num> <num> <num> <num>
1: 2005 3.0 3.5 2.5 2.0 2.3 1.7
2: 2006 3.1 3.5 2.6 2.0 2.3 1.7
3: 2007 5.0 4.2 5.8 2.5 3.0 2.0
我正在使用美国社区调查 (ACS) 对特定地点未来几年的 1 年估计。例如,我正在尝试绘制骑自行车上班的男性和女性比例随时间的变化情况。从 ACS 中,我得到估计值和标准误差,然后我可以用它来计算估计值的上限和下限。
所以宽格式的简化数据结构是这样的:
| Year | EstimateM | MaxM | MinM | EstimateF | MaxF | MinF |
|------|-----------|------|------|-----------|------|------|
| 2005 | 3.0 | 3.5 | 2.5 | 2.0 | 2.3 | 1.7 |
| 2006 | 3.1 | 3.5 | 2.6 | 2.0 | 2.3 | 1.7 |
| 2007 | 5.0 | 4.2 | 5.8 | 2.5 | 3.0 | 2.0 |
| ... | ... | ... | ... | ... | ... | ... |
如果我只想绘制估计值,我会 melt
只有两个 Estimate
变量的数据 measure.vars
GenderModeCombined_long <- melt(GenderModeCombined,
id = "Year",
measure.vars = c("EstimateM",
"EstimateF")
然后可以使用 ggplot2
ggplot(data=GenderModeCombined_long,
aes(x=year, y=value, colour=variable)) +
geom_point() +
geom_line()
这会生成这样的图表
(抱歉,post 图片没有足够的代表)
我卡住的地方是如何将误差线添加到两个估计图。我可以将它们作为 measure vars
添加到融化的数据集中,但是我如何告诉 ggplot 应该将什么绘制为值以及将什么绘制为误差线?我是否必须只使用 min/max 数据创建一个单独的数据框,然后单独加载它?
geom_errorbar(data = errordataMmax, aes(ymax = ??, ymin = ??))
我感觉我处理这个问题的方式不对and/or 我的数据设置有误。
欢迎来到 SO。这里的问题是你有三个 "explicit" 变量(估计, Min 和 Max)和一个 "implicit" 一个(性别),它在列名中编码。解决此问题的一种方法是使 "gender" 成为显式分组变量。转到长格式后,创建一个 "gender" 变量,从键列(变量)中删除性别指示,然后返回宽格式。 像这样的东西会起作用:
library(ggplot2)
library(dplyr)
library(tidyr)
library(tibble)
GenderModeCombined <- tibble::tribble(
~Year, ~EstimateM, ~MaxM, ~MinM, ~EstimateF, ~MaxF, ~MinF,
2005, 3.0, 3.5, 2.5, 2.0, 2.3, 1.7,
2006, 3.1, 3.5, 2.6, 2.0, 2.3, 1.7,
2007, 5.0, 4.2, 5.8, 2.5, 3.0, 2.0
)
GenderModeCombined.long <- GenderModeCombined %>%
# switch to long format
tidyr::gather(variable, value, -Year, factor_key = TRUE) %>%
# add a gender variable
dplyr::mutate(gender = stringr::str_sub(variable, -1)) %>%
# remove gender indication from the key column `variable`
dplyr::mutate(variable = stringr::str_sub(variable, end = -2)) %>%
# back to wide format
tidyr::spread(variable, value)
GenderModeCombined.long
#> # A tibble: 6 x 5
#> Year gender Estimate Max Min
#> <dbl> <chr> <dbl> <dbl> <dbl>
#> 1 2005 F 2 2.3 1.7
#> 2 2005 M 3 3.5 2.5
#> 3 2006 F 2 2.3 1.7
#> 4 2006 M 3.1 3.5 2.6
#> 5 2007 F 2.5 3 2
#> 6 2007 M 5 4.2 5.8
ggplot(data=GenderModeCombined.long,
aes(x=Year, y=Estimate,colour = gender)) +
geom_point() +
geom_line() +
geom_errorbar(aes(ymax = Max, ymin = Min))
由 reprex package (v0.2.1)
创建于 2018-12-29正如 Estimate
、Max
、Min
。
从版本 v1.9.6(2015 年 9 月 19 日在 CRAN 上)开始,data.table 的 melt()
函数的化身允许熔化,即从宽格式重塑为长格式,变成多个一口气列:
library(data.table)
options(datatable.print.class = TRUE)
cols <- c("Estimate", "Max", "Min")
long <- melt(setDT(GenderModeCombined), id.vars = "Year", measure.vars = patterns(cols),
value.name = cols, variable.name = "Gender")[
, Gender := forcats::lvls_revalue(Gender, c("M", "F"))][]
long
Year Gender Estimate Max Min <int> <fctr> <num> <num> <num> 1: 2005 M 3.0 3.5 2.5 2: 2006 M 3.1 3.5 2.6 3: 2007 M 5.0 4.2 5.8 4: 2005 F 2.0 2.3 1.7 5: 2006 F 2.0 2.3 1.7 6: 2007 F 2.5 3.0 2.0
现在,我们可以根据需要绘制每个 Year
和 Gender
的三个观察结果:
library(ggplot2)
ggplot(long, aes(x = Year, y = Estimate, colour = Gender)) +
geom_point() +
geom_line() +
geom_errorbar(aes(ymax = Max, ymin = Min), width = 0.1)
请注意,除了点和误差条之外,此图表还显示线条。这是因为 Year
是 整数 类型,ggplot2
将其识别为连续变量。
数据
data.table的fread()
函数读取各种数据格式非常得心应手。因此,我们只需稍作修改即可读取 OP 发布的数据:
library(data.table)
GenderModeCombined <- fread(
"| Year | EstimateM | MaxM | MinM | EstimateF | MaxF | MinF |
| 2005 | 3.0 | 3.5 | 2.5 | 2.0 | 2.3 | 1.7 |
| 2006 | 3.1 | 3.5 | 2.6 | 2.0 | 2.3 | 1.7 |
| 2007 | 5.0 | 4.2 | 5.8 | 2.5 | 3.0 | 2.0 |
", drop = c(1L, 9L))
GenderModeCombined
Year EstimateM MaxM MinM EstimateF MaxF MinF <int> <num> <num> <num> <num> <num> <num> 1: 2005 3.0 3.5 2.5 2.0 2.3 1.7 2: 2006 3.1 3.5 2.6 2.0 2.3 1.7 3: 2007 5.0 4.2 5.8 2.5 3.0 2.0