绘制已知错误的时间序列(ggplot2)

时间:2018-12-28 19:38:47

标签: r dataframe ggplot2 time-series errorbar

我正在使用美国社区调查(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()

这会产生一个像这样的图

Imgur

(对不起,没有足够的代表来发布图片)

我遇到的问题是如何在两个估算图中添加误差线。我可以将它们作为measure vars添加到已融化的数据集中,但是那又如何告诉ggplot应该以值形式绘制什么以及以误差棒形式绘制什么呢?我是否必须仅使用最小/最大数据创建一个单独的数据框,然后分别加载?

geom_errorbar(data = errordataMmax, aes(ymax = ??, ymin = ??)) 

我感觉自己正在以某种错误的方式进行处理和/或以错误的方式设置了数据。

2 个答案:

答案 0 :(得分:1)

欢迎来到SO。这里的问题是您有三个“显式”变量(估算值, 最小值和最大值)和一个以列名称编码的“隐式”(性别)。解决此问题的一种方法是使“性别”成为显式的分组变量。转到长格式后,创建一个“性别”变量,从键列(变量)中删除性别指示,然后返回宽格式。 这样的事情会起作用:

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创建

答案 1 :(得分:1)

正如lbusett所解释的那样,这个问题的答案与其说是绘图,不如说是将数据从宽格式转换为长格式。这里的挑战是每种性别都有多个值列,即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)

enter image description here

请注意,此图表还显示了除点和误差线以外的线。这是因为Year的类型为 integer ,而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