我的问题正是这个问题:
Plotting the "Average " curve of set of curves
但是我希望在ggplot中实现可接受的答案(如下)。有可能吗?
首先,我创建一些数据。在这里,我正在创建一个列表,其中包含5个data.frame,且具有不同的xs:
ll <- lapply(1:5,function(i)
data.frame(x=seq(i,length.out=10,by=i),y=rnorm(10)))
然后应用大约,我创建了一个包含所有数据的大data.frame:
big.df <- do.call(rbind,ll)
然后,我绘制线性近似值和所有序列:
plot(approx(big.df$x,big.df$y),type='l')
lapply(seq_along(ll),
function(i) points(ll[[i]]$x,ll[[i]]$y,col=i))
EDIT
我的数据结构(例如,实际DF包含183000行)
structure(list(timeseries = c(1, 7, 59, 0, 0, 5, 0, 0, 1, 0),
t = c(1, 3, 7, 1, 3, 7, 1, 3, 7, 1)), .Names = c("timeseries",
“ t”),row.names = c(NA,10L),class =“ data.frame”)
答案 0 :(得分:4)
在下面的代码中,我们从创建的列表开始(取决于您的实际数据是什么样,可能有更好的方法,但我现在将其保留)。然后,我们使用bind_rows
将其转换为单个数据帧,并使用mutate
添加内插值。我们将其动态地馈送到ggplot。 geom_line
绘制插值。
插值点是数据中每个x值的所有y值的精确平均值。为了进行比较,我还添加了geom_smooth
,它使用局部加权回归来绘制数据中的平滑曲线。 span
中的geom_smooth
参数可用于确定平滑程度。
library(tidyverse)
theme_set(theme_classic())
# Fake data
set.seed(2)
ll <- lapply(1:5,function(i)
data.frame(x=seq(i,length.out=10,by=i),y=rnorm(10)))
# Combine into single data frame and add interpolation column
bind_rows(ll, .id="source") %>%
mutate(avg = approx(x,y,xout=x)$y) %>%
ggplot(aes(x, y)) +
geom_point(aes(colour=source)) +
geom_line(aes(y=avg)) +
geom_smooth(se=FALSE, colour="red", span=0.3, linetype="11")
现在让我们完成各个数据处理步骤:
从列表中生成单个数据帧:
dat = bind_rows(ll, .id="source")
从该数据框中选择以下行:
dat[c(1:3, 15:17, 25:27), ]
source x y
1 1 1 -0.896914547
2 1 2 0.184849185
3 1 3 1.587845331
15 2 10 1.782228960
16 2 12 -2.311069085
17 2 14 0.878604581
25 3 15 0.004937777
26 3 18 -2.451706388
27 3 21 0.477237303
我们可以获得如下插值:
with(dat, approx(x, y, xout=x))
要获取上面我们想要的所有y值,我们可以这样做:
with(dat, approx(x, y, xout=x))$y
要将y值添加到数据框中:
dat$avg = with(dat, approx(x, y, xout=x))
要创建绘图,我们使用dplyr
包中的函数执行了数据处理步骤,该包是我们在代码开始时加载的tidyverse
包套件的一部分。它包含管道(%>%
)运算符,它使我们可以一个接一个地链接函数,并将数据直接馈送到ggplot
中,而不必将中间数据帧分配给对象(尽管我们如果愿意,可以先创建中间数据帧)。例如:
dat = bind_rows(ll, .id="source") %>%
mutate(avg = approx(x,y,xout=x)$y)
ggplot(dat, aes(x, y)) +
geom_point(aes(colour=source)) +
geom_line(aes(y=avg)) +
geom_smooth(se=FALSE, colour="red", span=0.3, linetype="11")