【问题标题】:xts - how to subset on each day of the weekxts - 如何在一周中的每一天进行子集化
【发布时间】:2016-05-18 22:27:04
【问题描述】:

我知道已经回答了类似的问题。我的问题是我有 2033 天的时间序列数据,间隔为 15 分钟。我想为每一天(周一至周日)绘制系列。例如星期一的平均情况。

我尝试使用 .indexwday 进行子集化,但当天的系列从 13:00 开始。

我是新手,所以如果我需要提供更多详细信息,请告诉我。

样本数据(xts)

  • 2008-01-01 00:00:00 16
  • 2008-01-01 00:15:00 56
  • 2008-01-01 00:30:00 136
  • 2008-01-01 00:45:00 170
  • 2008-01-01 01:00:00 132

....

  • 2013-07-25 22:30:00 95
  • 2013-07-25 22:45:00 82
  • 2013-07-25 23:00:00 66
  • 2013-07-25 23:15:00 65
  • 2013-07-25 23:30:00 66
  • 2013-07-25 23:45:00 46

下面的图可能更符合我的要求(这是所有星期一的平均值)

【问题讨论】:

  • 如果对共享不敏感,您能否提供数据的 sn-p?如果恰好是,请提供尺寸和结构相似的。

标签: r xts


【解决方案1】:

这里还有一个解决方案,不依赖xts和zoo以外的包。

# example data
ix <- seq(as.POSIXct("2008-01-01"), as.POSIXct("2013-07-26"), by="15 min")
set.seed(21)
x <- xts(sample(200, length(ix), TRUE), ix)

# aggregate by 15-minute observations for each weekday
a <- lapply(split.default(x, format(index(x), "%A")),         # split by weekday
  function(x) aggregate(x, format(index(x), "%H:%M"), mean))  # aggregate by 15-min
# merge aggregated data into one zoo object, ordering columns
z <- do.call(merge, a)[,c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")]
# convert index to POSIXct to make plotting easier
index(z) <- as.POSIXct(index(z), format="%H:%M")
# plot
plot(z, type="l", nc=1, ylim=range(z), main="Average daily volume", las=1)

设置ylim 会强制每个绘图具有相同的 y 轴范围。否则,它们将取决于每个单独的系列,如果值差异很大,这可能会使它们难以比较。

【讨论】:

    【解决方案2】:

    试试这个:

        #Get necessary packages
    install.packages("lubridate")
    install.packages("magrittr")
    install.packages("dplyr")
    install.packages("ggplot2")
    install.packages("scales")
    
    #Import packages
    library(lubridate,warn=F)
    library(dplyr,warn=F)
    library(magrittr)
    library(ggplot2,warn=F)
    library(scales, warn=F)
    
    #Getting the data
    tstart = as.POSIXct('2008-01-01 00:00:00')
    tend = as.POSIXct('2013-07-25 23:45:00')
    ttimes <- seq(from = tstart,to=tend,by='15 mins')
    tvals <- sample(seq(1,200),length(ttimes),T)
    tsdata <- data.frame(Dates=ttimes,Vals=tvals)
    tsdata <- tsdata %>% mutate(DayofWeek = wday(Dates,label=T), Hours = as.POSIXct(strftime(Dates,format="%H:%M:%S"),format="%H:%M:%S"))
    
    #Pick a day at a time. I am using Mondays for this example.
    tsdata_monday <- tsdata %>% filter(DayofWeek=='Mon') %>% group_by(Hours) %>% summarise(meanVals=mean(Vals)) %>% as.data.frame()
    
    #Plotting the graph of mean values versus times for Monday:
    ggplot(tsdata_monday) + aes(x=Hours,y=meanVals) + geom_line() + scale_x_datetime(breaks=date_breaks("4 hour"), labels=date_format("%H:%M"))
    

    #If you want you can go ahead and plot all the days. But please keep in mind
    #that this does not look good at all. Too many plots for the plot window to
    #Display nicely.
    alltsdata <- tsdata %>% group_by(DayofWeek, Hours) %>% summarise(MeanVals=mean(Vals)) %>% as.data.frame()
    
    ggplot(alltsdata) + aes(x=Hours,y=MeanVals) + geom_line() + scale_x_datetime(breaks=date_breaks("4 hour"), labels=date_format("%H:%M")) + facet_grid(.~DayofWeek)
    

    我建议您一次绘制一天或使用for loopapply 函数变体之一来获取绘图。

    此外,在按星期几过滤时,请注意天数缩短如下:

    unique(tsdata$DayofWeek)
    [1] Tues  Wed   Thurs Fri   Sat   Sun   Mon 
    

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      apply.daily 完全符合您的要求。(假设您的数据称为 d.xts 和 xts 对象)

      apply.daily(d.xts,sum)
      

      另一种解决方案是使用aggregate:

      aggregate(d.xts,as.Date(index(d.xts)),sum)
      

      请注意,答案略有不同:apply.dailystart(d.xts) to end(d.xts) 开始,而aggregate 从午夜到午夜。

      【讨论】:

        猜你喜欢
        • 2013-04-20
        • 1970-01-01
        • 2012-12-04
        • 2012-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-07
        • 2015-12-01
        相关资源
        最近更新 更多