【问题标题】:subsetting and performing calculations on time series data, avoiding loops对时间序列数据进行子集化和计算,避免循环
【发布时间】:2013-07-29 18:50:52
【问题描述】:

我试图弄清楚如何在不循环的情况下执行以下操作。我有一个融合的时间、研究地点和流程数据集,如下所示:

日期时间网站流程
2009 年 6 月 1 日 00:00 EBT 北美
2009 年 6 月 2 日 01:00 EBT 北美
2009 年 6 月 3 日 02:00 EBT 0.1
2009 年 6 月 4 日 03:00 EBT 北美
2009 年 6 月 5 日 04:00 EBT 北美
2009 年 6 月 1 日 00:00 MUT 0.4
2009 年 6 月 2 日 01:00 MUT 0.3
2009 年 6 月 3 日 02:00 MUT 0.2
2009 年 6 月 4 日 03:00 MUT NA
2009 年 6 月 5 日 04:00 MUT NA

我需要按站点对其进行子集化,然后在至少有两个后续流量测量的时间段内,我需要执行几个计算,*例如当前和先前测量的平均值。

诀窍是我需要对每组连续测量进行平均,即如果后两个连续测量三个,我需要该测量的平均值和前一个测量的平均值。我在示例数据框中添加了一个目标列,其中包含我想要获得的结果。*

我希望得到一个外观相似的数据框,其中包含日期时间、站点和计算结果。每个站点都有一个完整的时间序列。

感谢您的帮助!

数据生成器:

structure(list(datetime = structure(c(1167627600, 1167717600, 
1167807600, 1167897600, 1167987600, 1167627600, 1167717600, 1167807600, 
1167897600, 1167987600, 1168077600, 1168167600, 1168257600, 1168347600, 
1168437600), class = c("POSIXct", "POSIXt"), tzone = ""), site = structure(c(1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("EBT", 
"MUT"), class = "factor"), flow = c(NA, 0.1, NA, NA, NA, NA, 
0.4, 0.2, NA, NA, 0.4, 0.2, 0.1, NA, NA), goal = c(NA, NA, NA, 
NA, NA, NA, NA, 0.3, NA, NA, NA, 0.3, 0.15, NA, NA)), .Names = c("datetime", 
"site", "flow", "goal"), row.names = c(NA, -15L), class = "data.frame")

【问题讨论】:

  • 您能否提供您正在寻找的结果数据集?您可以使用 R 中的许多工具轻松做到这一点...library(data.table); s=data.table(sample); s[, mean(flow), by=site]...
  • 编辑问题更清晰,并添加示例输出。谢谢!

标签: r time-series subset


【解决方案1】:

这将通过site 分隔您的数据框,然后仅过滤在flow 中具有两个或多个连续非NA 值的行:

by(sample, sample$site, function(d) d[with(rle(!is.na(d$flow)), rep(values & lengths>=2, lengths)),])

然后您可以根据需要处理内部函数以进行计算。

例如,如果您想将均值添加为新列(假设您希望 NA 未定义),您可以使用:

f <- function(d)
{
    x <- with(rle(!is.na(d$flow)), rep(values & lengths>=2, lengths))

    within(d, {avg <- NA; avg[x] <- mean(d[x,"flow"])})
}

b <- by(sample, sample$site, f)

Reduce(rbind, b)

结果:

              datetime site flow avg
1  2009-06-01 01:00:00  EBT   NA  NA
2  2009-06-02 02:00:00  EBT   NA  NA
3  2009-06-03 03:00:00  EBT  0.1  NA
4  2009-06-04 04:00:00  EBT   NA  NA
5  2009-06-05 05:00:00  EBT   NA  NA
6  2009-06-01 01:00:00  MUT  0.4 0.3
7  2009-06-02 02:00:00  MUT  0.3 0.3
8  2009-06-03 03:00:00  MUT  0.2 0.3
9  2009-06-04 04:00:00  MUT   NA  NA
10 2009-06-05 05:00:00  MUT   NA  NA

编辑:要获得当前流量测量值与前一个流量测量值之间的平均值,您可以使用:

f <- function(d)
{
    within(d, avg <- (flow+c(NA,head(flow,-1)))/2)
}

Reduce(rbind, by(sample, sample$site, f))

请注意,具有单个度量的案例会自动设置为NA。新结果:

              datetime site flow goal  avg
1  2007-01-01 03:00:00  EBT   NA   NA   NA
2  2007-01-02 04:00:00  EBT  0.1   NA   NA
3  2007-01-03 05:00:00  EBT   NA   NA   NA
4  2007-01-04 06:00:00  EBT   NA   NA   NA
5  2007-01-05 07:00:00  EBT   NA   NA   NA
6  2007-01-01 03:00:00  MUT   NA   NA   NA
7  2007-01-02 04:00:00  MUT  0.4   NA   NA
8  2007-01-03 05:00:00  MUT  0.2 0.30 0.30
9  2007-01-04 06:00:00  MUT   NA   NA   NA
10 2007-01-05 07:00:00  MUT   NA   NA   NA
11 2007-01-06 08:00:00  MUT  0.4   NA   NA
12 2007-01-07 09:00:00  MUT  0.2 0.30 0.30
13 2007-01-08 10:00:00  MUT  0.1 0.15 0.15
14 2007-01-09 11:00:00  MUT   NA   NA   NA
15 2007-01-10 12:00:00  MUT   NA   NA   NA

【讨论】:

  • 费迪南德,这非常接近。谢谢!但是,这会计算每个站点满足标准的所有流量的平均值。我应该更清楚的是,我需要对每组进行计算。我已经将问题编辑得更清楚,并向样本集中添加了一些数据,以及我要拍摄的输出。再次感谢!
【解决方案2】:

Plyr 函数是通过某些变量拆分数据帧的好方法,这是您需要做的。

我想到了两种处理向量区间的方法:第一种是向量乘法(用于数据的平均值),第二种是向量化函数(用于生成标签)。不过,他们都在做几乎相同的事情。

library(reshape2)
library(plyr)
library(lubridate)

meanBetween <- function(x){
  l <- length(x)
  diag(outer(x[1:(l-1)], x[2:l], "+"))/2
}

output <- ddply(sample, .(site), function(df){
  df <- df[order(df$datetime, decreasing=FALSE), ]
  result <- meanBetween(df$flow)
  names(result) <- Reduce(c, (mapply(as.interval,
                                     df$datetime[-1],
                                     df$datetime[1:(length(df$datetime)-1)],
                                     SIMPLIFY=FALSE)))
  result
})

melt(output) # to make it look nicer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    相关资源
    最近更新 更多