在ggplot2中绘制移动平均线

14

我希望创建一个图表,在散点图上显示一条运行平均线,以展示观测数据的趋势。数据包括野兔毛色(Color)随时间(Julian)的观测结果。

Color  Julian
50  85
50  87
50  89
50  90
100 91
50  91
50  92
50  92
100 92
50  93
100 93
50  93
50  95
100 95
50  95
50  96
50  96
50  99
50  100
0   101
0   101
0   103
50  103
50  104
50  104
50  104
50  104
100 104
100 104
50  109
50  109
100 109
0   110
0   110
50  110
50  110
50  110
50  110
0   112

我的朋友为我写了一个函数,用于计算颜色观测的运行平均值,但我不知道如何将该行(haresAveNoNa)添加到图表中。

该函数:

haresAverage <- matrix( NA, max(hares$Julian), 3 )
for( i in 4:max(hares$Julian) ){
  haresAverage[i,1]<-i
  haresAverage[i,2]<-mean( hares$Color[ hares$Julian >= (i-3) &
                                             hares$Julian <= (i+3)]
                              , na.rm=T )
  haresAverage[i,3]<-sd( hares$Color[ hares$Julian >= (i-3) &
                                           hares$Julian <= (i+3)]

                            , na.rm=T )
}
haresAveNoNa <- na.omit( haresAverage)

剧情简介:
p <- ggplot(hares, aes(Julian, Color))
p  +
  geom_jitter(width = 1, height = 5, color="blue", alpha = .65) 

请帮我将运行平均值'haresAveNoNa'添加到图表中,非常感谢!


1
R生态系统中新增了一个名为tidyquant的软件包,并且其中包含有geom_ma函数,可以轻松地将移动平均线添加到ggplot中。 - Andrew Borst
1个回答

33

您可以使用zoo包中的rollmean来计算滚动均值,而无需编写自己的函数。您可以在ggplot内部即时调用rollmean以添加滚动平均线,或者您可以将滚动平均值添加到数据框中,然后绘制它们。下面为两种方法都提供了示例。以下代码计算带有七天窗口的中心滚动平均值,但是您可以自定义函数以适应不同窗口大小和左对齐或右对齐的滚动平均值,而不是居中。

ggplot内部即时计算滚动平均值

library(zoo)

ggplot(hares, aes(Julian, Color)) + 
  geom_point(position=position_jitter(1,3), pch=21, fill="#FF0000AA") +
  geom_line(aes(y=rollmean(Color, 7, na.pad=TRUE))) +
  theme_bw()

输入图像描述

将滚动均值作为新列添加到数据框中,然后绘制它

为了回答您的具体问题,假设您确实需要从单独的数据中添加滚动均值线,而不是即时计算。如果滚动均值是数据框中的另一列,则只需将新列名称提供给geom_line

hares$roll7 = rollmean(hares$Color, 7, na.pad=TRUE)

ggplot(hares, aes(Julian, Color)) + 
  geom_point(position=position_jitter(1,3), pch=21, fill="#FF0000AA") +
  geom_line(aes(y=roll7)) +
  theme_bw()

使用单独的数据框为绘图添加滚动均值

如果滚动均值存在于单独的数据框中,您需要将该数据框提供给geom_line

haresAverage = data.frame(Julian=hares$Julian, 
                          Color=rollmean(hares$Color, 7, na.pad=TRUE))

ggplot(hares, aes(Julian, Color)) + 
  geom_point(position=position_jitter(1,3), pch=21, fill="#FF0000AA") +
  geom_line(data=haresAverage, aes(Julian, Color)) +
  theme_bw()

更新:显示日期而不是数字的儒略日值

首先,将儒略日转换为日期格式。我不知道您的数据中从儒略日到日期的实际映射,因此在此示例中,让我们假设儒略日表示一年中的某一天,以第一天为1,并假设该年份为2015年。

hares$Date = as.Date(hares$Julian + as.numeric(as.Date("2015-01-01")) - 1)

现在我们使用新的Date列作为x轴进行绘图。要自定义断点数量和日期标签,请使用scale_x_date

ggplot(hares, aes(Date, Color)) + 
  geom_point(position=position_jitter(1,3), pch=21, fill="#FF0000AA") +
  geom_line(aes(y=rollmean(Color, 7, na.pad=TRUE))) +
  theme_bw() +
  scale_x_date(date_breaks="weeks", date_labels="%b %e")

在此输入图片描述


1
非常感谢您的帮助!代码运行得很好,但是线条非常尖锐(无论窗口大小如何)。是否可以使用不同的计算或某种曲线函数创建更平滑的趋势线?我尝试了默认方法loess的geom_smooth,但在某些时期当所有动物都具有极端值或者增加跨度值时,该线会在最小和最大颜色值之下和之上波动。此外,是否可以更改x轴以显示实际日期而不是儒略日期(我的数据包括一个额外的列日期,格式为MM/DD/YYYY)?谢谢! - Kestrel1
我已经添加了一个关于如何在x轴上获取日期值的更新。 - eipi10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接