我有来自xts对象的不规则时间索引。我需要找到两次观察之间的 平均秒数。 这是我的示例数据:
dput(tt)
structure(c(1371.25, NA, 1373.95, NA, NA, 1373, NA, 1373.95,
1373.9, NA, NA, 1374, 1374.15, NA, 1374, 1373.85, 1372.55, 1374.05,
1374.15, 1374.75, NA, NA, 1375.9, 1374.05, NA, NA, NA, NA, NA,
NA, NA, 1375, NA, NA, NA, NA, NA, 1376.35, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, 1376.25, NA, 1378, 1376.5, NA, NA, NA, 1378,
1378, NA, NA, 1378.8, 231.9, 231.85, NA, 231.9, 231.85, 231.9,
231.8, 231.9, 232.6, 231.95, 232.35, 232, 232.1, 232.05, 232.05,
232.05, 231.5, 231.3, NA, NA, 231.1, 231.1, 231.1, 231, 231,
230.95, 230.6, 230.6, 230.7, 230.6, 231, NA, 231, 231, 231.45,
231.65, 231.4, 231.7, 231.3, 231.25, 231.25, 231.4, 231.4, 231.85,
231.75, 231.5, 231.55, 231.35, NA, 231.5, 231.5, NA, 231.5, 231.25,
231.15, 231, 231, 231, 231.05, NA), .Dim = c(60L, 2L), .indexCLASS = c("POSIXct",
"POSIXt"), tclass = c("POSIXct", "POSIXt"), .indexTZ = "Asia/Calcutta", tzone = "Asia/Calcutta", index = structure(c(1459482299,
1459482301, 1459482302, 1459482303, 1459482304, 1459482305, 1459482306,
1459482307, 1459482309, 1459482310, 1459482311, 1459482312, 1459482314,
1459482315, 1459482316, 1459482317, 1459482318, 1459482319, 1459482320,
1459482321, 1459482322, 1459482323, 1459482324, 1459482326, 1459482328,
1459482329, 1459482330, 1459482331, 1459482332, 1459482336, 1459482337,
1459482338, 1459482339, 1459482342, 1459482344, 1459482346, 1459482347,
1459482348, 1459482349, 1459482590, 1459482591, 1459482594, 1459482595,
1459482596, 1459482597, 1459482598, 1459482599, 1459482602, 1459482603,
1459482604, 1459482609, 1459482610, 1459482611, 1459482612, 1459482613,
1459482618, 1459482619, 1459482620, 1459482622, 1459482628), tzone = "Asia/Calcutta", tclass = c("POSIXct",
"POSIXt")), .Dimnames = list(NULL, c("A", "B")), class = c("xts",
"zoo"))
这是我的尝试:
difftime(index(tt),index(lag.xts(tt, k=1)), units=c("auto"))
Time differences in secs
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
attr(,"tclass")
[1] "POSIXct" "POSIXt"
非常感谢任何帮助。
编辑:
根据答案,我制作了以下代码。 该代码用于计算每天A和B的平均秒数。
但代码采用tt而不是A或B的索引,因此A和B的结果相同。
fun.time= function(x) mean(diff(time(x)))
df.time<-do.call(rbind, lapply(split(tt, "days"), FUN=function (x) {do.call(cbind, lapply(as.list(x), fun.time))}))
dput(df.time)
structure(c(5.57627118644068, 5.57627118644068), .Dim = 1:2, .Dimnames = list(
NULL, c("A", "B")))
答案 0 :(得分:6)
首先创建一些超过一天的测试数据。使用我们创建的tt
问题中的tt2
。
其余代码在删除该列的NA值后按列和按天计算连续时间的差异。我们按日期lapply
对列进行了aggregate
我们format
。为此,我们删除当前列的NA,然后构造一个zoo对象,其值为数字秒,其索引是格式化的时间。数值是这样的,我们可以避免处理difftime对象及其不可预测的单位,as.Date
导致tzone
获取相对于数据的as.Date
属性的日期;否则,as.xts
将取相对于GMT的日期而不是所需的日期(基于下面海报的评论)。这将返回一个zoo对象,但如果xts输出很重要,那么将library(xts)
# test input
tt2 <- tt
time(tt2) <- time(tt) + seq(1, 24*60*60, length = 60)
do.call(cbind, lapply(tt2, function(x) {
times <- time(na.omit(x))
aggregate(zoo(as.numeric(times), format(times)), as.Date, function(x) mean(diff(x)))
}))
应用于结果很容易。
A B
2016-04-01 3029.0 1648.9
2016-04-02 5416.1 1633.0
给出以下动物园系列:
aggregate
注1:如果我们只需要按列而不是按日期的平均差异,那么我们可以将tt
简化为以下单行代码。在这里,我们回到使用sapply(tt, function(x) mean(diff(as.numeric(time(na.omit(x))))))
作为测试输入,因为这足以说明这种情况。请注意,我们再次将索引转换为数字,以避免difftime输出单元的不可预测性。
A B
14.9545 6.2115
给出这个命名的数字向量:
coredata
注2:使用development version of zoo,这可以简化。在该版本的zoo中,aggregate.zoo
存在FALSE
参数,如果设置为coredata
,则整个zoo对象将被发送到函数而不仅仅是tzone
部分。在下面的代码中,我们定义函数以获取NA删除后的平均差异并将索引转换为字符,然后将Date转换为使用输入的aggregate.zoo
属性作为其时区(或当地时间)的效果区)。然后,我们将cbind
按日期应用于每列,并library(xts)
mean_diff_time <- function(x) mean(diff(as.numeric(time(na.omit(x)))))
dates <- function(x) as.Date(format(x))
do.call("cbind", lapply(as.zoo(tt2), aggregate, dates, mean_diff_time, coredata = FALSE))
将结果列表重新组合在一起:
activationStrategy
更新:重新安排了演示文稿。
答案 1 :(得分:2)
为了补充G.Grothendieck的答案,您还可以使用mean(diff(index(tt)))
将结果作为difftime
对象返回:
> mean(diff(index(tt)))
Time difference of 5.576271 secs
或只是mean(diff(.index(tt)))
将结果设为数字:
> mean(diff(.index(tt)))
[1] 5.576271
编辑:
> lapply(tt, function(x){mean(diff(.index(x[!is.na(x)])))})
$A
[1] 14.95455
$B
[1] 6.211538