我正在使用美国社区调查(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()
这会产生一个像这样的图
(对不起,没有足够的代表来发布图片)
我遇到的问题是如何在两个估算图中添加误差线。我可以将它们作为measure vars
添加到已融化的数据集中,但是那又如何告诉ggplot应该以值形式绘制什么以及以误差棒形式绘制什么呢?我是否必须仅使用最小/最大数据创建一个单独的数据框,然后分别加载?
geom_errorbar(data = errordataMmax, aes(ymax = ??, ymin = ??))
我感觉自己正在以某种错误的方式进行处理和/或以错误的方式设置了数据。
答案 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所解释的那样,这个问题的答案与其说是绘图,不如说是将数据从宽格式转换为长格式。这里的挑战是每种性别都有多个值列,即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
的类型为 integer ,而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