在GGPLOT中绘制曲线组的“平均”曲线

时间:2018-10-04 02:56:51

标签: r ggplot2

我的问题正是这个问题:

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”)

1 个答案:

答案 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")

enter image description here

现在让我们完成各个数据处理步骤:

  1. 从列表中生成单个数据帧:

    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
    
  2. 我们可以获得如下插值:

     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")