绘制具有已知错误的时间序列 (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

正如 所解释的那样,这个问题的答案与其说是关于绘图,不如说是关于将数据从宽格式重塑为长格式。这里的挑战是每个性别都有多个值列,即 EstimateMaxMin

从版本 v1.9.6(2015 年 9 月 19 日在 CRAN 上)开始,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

现在,我们可以根据需要绘制每个 YearGender 的三个观察结果:

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 将其识别为连续变量。

数据

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