我有大量的电压读数数据。我希望确定电压高于阈值的不同时间段的频率。因此,对于电压子集(>=2V),我希望计算电压基于1秒采样间隔的连续周期的长度。参见下面的示例数据:
library(chron)
volts=c(2,3,4,5,6,2,2,3,4,5,5,5)
t=chron(times=c("23:03:20", "23:03:21", "23:03:22", "23:03:23","23:03:24","23:03:25","04:01:50","04:01:51","04:01:52","04:01:53","04:01:54","04:01:55"))
data=data.frame(volts,"time"=t)此示例包含两个序列,一个从23:03:20到23:03:25,另一个从04:01:50到04:01:55。
我希望计算这些周期的持续时间和大量数据的平均电压,条件是周期之间有30秒,以便它们被认为是离散的。我想我的答案可能取决于动物园,我欢迎大家的建议。
发布于 2013-07-31 05:43:01
在输出中使用与@BenBolker相同的名称:
library(data.table)
dt = data.table(data)
dt[, time := as.ITime(time)] # easier to deal with
dt[, list(meanvolts = mean(volts), duration = time[.N] - time[1], n = .N),
by = list(period = 1 + c(0, cumsum(abs(diff(time)) >= 30)))]
# period meanvolts duration n
#1: 1 3.666667 00:00:05 6
#2: 2 4.000000 00:00:05 6发布于 2013-07-31 05:19:44
使用zoo可能会有一个更有效的解决方案,但是如何:
样本数据(为方便起见重复)
library(chron)
dat <- data.frame(volts=c(2,3,4,5,6,2,2,3,4,5,5,5),
time=chron(times=c("23:03:20", "23:03:21", "23:03:22",
"23:03:23","23:03:24","23:03:25",
"04:01:50","04:01:51","04:01:52","04:01:53",
"04:01:54","04:01:55")))分析:
daysecs <- 3600*24
dd <- c(unclass(diff(dat$time))*daysecs) ## difference in seconds
## classify jumps to new periods, including day boundaries
## (I haven't tested this carefully!)
new_per <- !((dd>0 & dd<30) | (dd<0 & dd<(-daysecs+30)))
dat$period <- 1+c(0,cumsum(new_per)) ## a fairly standard trick
library(plyr)
ddply(dat,.(period),summarise,
meanvolts=mean(volts),
duration=tail(time,1)-time[1],
n=length(volts))结果:
## period meanvolts duration n
## 1 1 3.666667 00:00:05 6
## 2 2 4.000000 00:00:05 6plyr不是特别快,但我会在你的数据上尝试一下,看看它的速度是否可以接受,然后再回来,让我们了解它必须有多快(要么编辑你的问题(“我有600万个电压测量...")或发布一个链接到此问题的新问题)
发布于 2013-07-31 05:41:49
这里是一个解决方案xts包。通常我们使用period.apply函数来处理这类时间序列过程。实际上,在这里,我只是使用endpoints创建拆分器索引(每次30秒),然后使用经典的sapply循环。
library(xts)
## creating the `xts` objects.
x.z <- xts(data$volts,
as.POSIXct(strptime(data$time,format='%H:%M:%S')))
INDEX <- endpoints(x.z,'secs',30)
xx <- sapply(1:(length(INDEX) - 1), function(y) {
x <- x.z[(INDEX[y] + 1):INDEX[y + 1]]
data.frame(period=y,
duration=diff(range(index(x))),
mm = mean(x),
len = length(x))
})
t(xx)
period duration mm len
[1,] 1 5 4 6
[2,] 2 5 3.666667 6 编辑 endpoints如何处理时间索引超出天界限的特殊情况?
创建一个示例:
## creating xts object index
ii <- as.POSIXct(strptime(data$time,format='%H:%M:%S'))
## here I add day to simulate day boundary
ii[6] <- as.POSIXct(ii[6] + as.difftime(1,units='days'))现在我时间序列看起来像这样:
x.z
[,1]
2013-07-31 04:01:50 2
2013-07-31 04:01:51 3
2013-07-31 04:01:52 4
2013-07-31 04:01:53 5
2013-07-31 04:01:54 5
2013-07-31 04:01:55 5
2013-07-31 23:59:55 2
2013-07-31 23:59:56 3
2013-07-31 23:59:57 4
2013-07-31 23:59:58 5
2013-07-31 23:59:59 6
2013-08-01 00:00:02 2 ## day boundaries here应用相同的代码(解决方案的开始),我们得到3 periods,而不是预期的2
t(xx)
period duration mm len
[1,] 1 5 4 6
[2,] 2 4 4 5
[3,] 3 0 2 1 ## 2013-08-01 00:00:02 2 https://stackoverflow.com/questions/17957279
复制相似问题