title: "ggplot2时间序列图中x轴为分类变量的处理"
author: "wintryheart"
date: "2019/7/2"
output: html_document
knitr::opts_chunk$set(echo = TRUE)
缘起
我想做一个时间序列图,但时间轴的标签是年份区间,而不是具体年份,所以不能转成date型变量,而用的是字符型。
在使用ggplot2作图时,碰到“geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?”错误提示。
数据
bdrate <- read.csv("c:\\users\\liang\\desktop\\death_birth_rate.csv")
bdrate <- tidyr::unite(bdrate, "seyear", startyear, endyear,sep="-",remove=F)
bdrate_spread1 <- reshape2::dcast(bdrate, seyear~region, value.var = "birthrate")
names(bdrate_spread1) <- c("seyear", "br_develped", "br_developing")
str(bdrate_spread1)
knitr::kable(head(bdrate_spread1))
seyear | br_develped | br_developing |
---|---|---|
1750-1800 | 38 | 41 |
1800-1850 | 39 | 41 |
1850-1900 | 38 | 40 |
1900-1910 | 34 | 41 |
1910-1920 | 26 | 40 |
1920-1930 | 28 | 41 |
问题
ggplot(bdrate_spread1, aes(x=seyear, y=br_develped))+geom_line()
返回错误提示:
原因
x轴的变量为分类数据。geom_line()它会根据分类变量自动分组。由于数据框中每个分类只有一个数据,ggplot无法画线。
另一个例子,每个年份对应两个地区的数据(region变量)。
str(bdrate)
knitr::kable(head(bdrate))
library(ggplot2)
ggplot(bdrate, aes(x=seyear, y=birthrate)) +
geom_line() +
theme(axis.text.x = element_text(angle = 45, hjust=1))
seyear | startyear | endyear | region | birthrate | deathrate |
---|---|---|---|---|---|
1750-1800 | 1750 | 1800 | 发达地区 | 38 | 34 |
1800-1850 | 1800 | 1850 | 发达地区 | 39 | 32 |
1850-1900 | 1850 | 1900 | 发达地区 | 38 | 29 |
1900-1910 | 1900 | 1910 | 发达地区 | 34 | 21 |
1910-1920 | 1910 | 1920 | 发达地区 | 26 | 23 |
1920-1930 | 1920 | 1930 | 发达地区 | 28 | 16 |
虽然没有提示错误,但很显然不是我们想要的图。事实上每个线段代表的是各年份区间出生率和死亡率的差距。
正确的画法是
ggplot(bdrate, aes(x=seyear, y=birthrate, group=region)) +
geom_line() +
theme(axis.text.x = element_text(angle = 45, hjust=1))
2.png
解决办法
解决问题的关键就在于group参数的设置,告诉ggplot只有一个组,即设置参数group=1。
ggplot(bdrate_spread1, aes(x=seyear, y=br_develped, group=1)) +
geom_line() +
theme(axis.text.x = element_text(angle = 45, hjust=1))
3.png
网友评论