首页 > 解决方案 > Plotting the “Average ” curve of set of curves in GGPLOT

问题描述

My Question is exactly this one:

Plotting the "Average " curve of set of curves

but I am looking to implement the accepted answer (below) in ggplot. is it possible?

First I create some data. Here I am creating a list , with 5 data.frame, with differents xs:

 ll <- lapply(1:5,function(i)
  data.frame(x=seq(i,length.out=10,by=i),y=rnorm(10)))

Then to apply approx, I create a big data.frame containing all the data:

big.df <- do.call(rbind,ll)

Then , I plot the linear approximation and all my series :

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

structure of my data (example. the actual DF contain 183000 rows)

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

标签: rggplot2

解决方案


在下面的代码中,我们从您创建的列表开始(取决于您的实际数据是什么样的,可能有更好的方法,但我暂时保留它)。然后我们使用bind_rows将其转换为单个数据框并mutate添加插值。我们动态地将它喂给ggplot。geom_line绘制插值。

插值点是数据中每个 x 值处所有 y 值的精确平均值。为了比较,我还添加了geom_smooth,它使用局部加权回归在数据中绘制平滑曲线。span参数 in可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")

在此处输入图像描述

现在让我们来看看各个数据处理步骤:

  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它包括 pipe ( %>%) 运算符,它允许我们一个接一个地链接函数并将数据直接输入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")

推荐阅读