我正在尝试使用ggplot在一个时间序列中绘制多个趋势线(每十年)。
以下是数据:
dat <- structure(list(YY = 1961:2010, a = c(98L, 76L, 83L, 89L, 120L,
107L, 83L, 83L, 92L, 104L, 98L, 91L, 81L, 69L, 86L, 76L, 85L,
86L, 70L, 81L, 77L, 89L, 60L, 80L, 94L, 66L, 77L, 85L, 77L, 80L,
79L, 79L, 65L, 70L, 80L, 87L, 84L, 67L, 106L, 129L, 95L, 79L,
67L, 105L, 118L, 85L, 86L, 103L, 97L, 106L)), .Names = c("YY",
"a"), row.names = c(NA, -50L), class = "data.frame")
这是脚本:
p <- ggplot(dat, aes(x = YY))
p <- p + geom_line(aes(y=a),colour="blue",lwd=1)
p <- p + geom_point(aes(y=a),colour="blue",size=2)
p <- p + theme(panel.background=element_rect(fill="white"),
plot.margin = unit(c(0.5,0.5,0.5,0.5),"cm"),
panel.border=element_rect(colour="black",fill=NA,size=1),
axis.line.x=element_line(colour="black"),
axis.line.y=element_line(colour="black"),
axis.text=element_text(size=15,colour="black",family="serif"),
axis.title=element_text(size=15,colour="black",family="serif"),
legend.position = "top")
p <- p + scale_x_discrete(limits = c(seq(1961,2010,5)),expand=c(0,0))
p <- p + geom_smooth(data=dat[1:10,],aes(x=YY,y=a),method="lm",se=FALSE,color="black",formula=y~x,linetype="dashed")
p <- p + geom_smooth(data=dat[11:20,],aes(x=YY,y=a),method="lm",se=FALSE,color="black",formula=y~x,linetype="dashed")
p <- p + geom_smooth(data=dat[21:30,],aes(x=YY,y=a),method="lm",se=FALSE,color="black",formula=y~x,linetype="dashed")
p <- p + geom_smooth(data=dat[31:40,],aes(x=YY,y=a),method="lm",se=FALSE,color="black",formula=y~x,linetype="dashed")
p <- p + geom_smooth(data=dat[41:50,],aes(x=YY,y=a),method="lm",se=FALSE,color="black",formula=y~x,linetype="dashed")
p <- p + labs(x="Year",y="Number of Days")
outImg <- paste0("test",".png")
ggsave(outImg,p,width=8,height=5)
这是生成的图像:
我要/问题
我想提取斜率并将其添加到图中的趋势线上。如何从geom_smooth()中提取每条线的斜率?
当前,我正在逐一绘制趋势线。我想知道是否存在一种可调整时间窗口的有效方法。例如,假设我要绘制每5年的趋势线。在上图中的时间窗口为10。
假设我只想绘制显着的趋势线(即p值<0.05,null:没有趋势或斜率等于0),是否可以使用geom_smooth()实现?
我将不胜感激。
答案 0 :(得分:5)
因此,在将数据通过管道传输到ggplot2之前,这些任务中的每一个都得到了最好的处理,但是使用tidyverse的其他一些软件包,它们都变得相当容易。
从问题1和问题2开始:
尽管ggplot2可以绘制回归线,但要提取估计的斜率系数,您需要显式使用lm()
对象。使用group_by()
和mutate()
,您可以添加分组变量(例如,我的下面的代码仅对5年组进行此操作),然后仅将斜率估算值提取并提取到现有数据框中的列中。然后可以使用geom_text()
调用将这些斜率估计值绘制在ggplot中。我在下面以一种快速而肮脏的方式进行了此操作(将每个标签放置在它们回归的x和y值的平均值处),但是您可以在数据框中指定它们的确切位置。
分组变量和数据准备也使问题2变得轻而易举:既然您已经在数据框中明确地有了分组变量,就无需一一画出了,geom_smooth()
接受了group
的美感。
此外,要回答问题3,您可以从lm对象的摘要中提取pvalue并仅过滤出对您关心的级别有意义的那些pvalue。如果将现在完整的数据框传递给geom_smooth()
和geom_text()
,您将得到想要的绘图!
library(tidyverse)
# set up our base plot
p <- ggplot(dat, aes(x = YY, y = a)) +
geom_line(colour = "blue", lwd = 1) +
geom_point(colour = "blue", size = 2) +
theme(
panel.background = element_rect(fill = "white"),
plot.margin = unit(c(0.5, 0.5, 0.5, 0.5), "cm"),
panel.border = element_rect(colour = "black", fill = NA, size = 1),
axis.line.x = element_line(colour = "black"),
axis.line.y = element_line(colour = "black"),
axis.text = element_text(size = 15, colour = "black", family = "serif"),
axis.title = element_text(size = 15, colour = "black", family = "serif"),
legend.position = "top"
) +
scale_x_discrete(limits = c(seq(1961, 2010, 5)), expand = c(0, 0))
# add a grouping variable (or many!)
prep5 <- dat %>%
mutate(group5 = rep(1:10, each = 5)) %>%
group_by(group5) %>%
mutate(
slope = round(lm(YY ~ a)$coefficients[2], 2),
significance = summary(lm(YY ~ a))$coefficients[2, 4],
x = mean(YY), # x coordinate for slope label
y = mean(a) # y coordinate for slope label
) %>%
filter(significance < .2) # only keep those with a pvalue < .2
p + geom_smooth(
data = prep5, aes(x = YY, y = a, group = group5), # grouping variable does the plots for us!
method = "lm", se = FALSE, color = "black",
formula = y ~ x, linetype = "dashed"
) +
geom_text(
data = prep5, aes(x = x, y = y, label = slope),
nudge_y = 12, nudge_x = -1
)
现在,在指定文本标签的位置时,您可能要比我在这里要小心一些。我使用了均值和nudge_*
的{{1}}参数来做一个简单的例子,但是请记住,因为这些值被显式映射到x和y坐标,所以您可以完全控制!
由reprex package(v0.2.0)于2018-07-16创建。