我有一个有两个参数的数据,它们是数据/时间和流量。流量数据是间歇流量。让我们说有时零流量突然流量开始,有时会出现非零值,然后流量再次为零。我想了解何时出现非零值以及每个非零流程持续多长时间。我已将样本数据集附加到此位置https://www.dropbox.com/s/ef1411dq4gyg0cm/sampledataflow.csv
数据是1分钟数据。
我能够将数据导入R,如下所示:
flow <- read.csv("sampledataflow.csv")
summary(flow)
names(flow) <- c("Date","discharge")
flow$Date <- strptime(flow$Date, format="%m/%d/%Y %H:%M")
sapply(flow,class)
plot(flow$Date, flow$discharge,type="l")
我制作的情节可以看到分布,但无法知道从哪里开始获取每个非零值的频率。我想看一个输出表如下:
Date Duration in Minutes
如果我在这里不清楚,请告诉我。谢谢。
其他信息:
我认为我们需要首先检查非零值,然后再次找到有多少非零值再次达到零值。我想要了解的是流量释放持续时间。例如。在一天内可能有多个版本,我想要注意发布的开始时间以及它在达到零值之前还有多长时间。我希望这能更好地解释问题。
答案 0 :(得分:3)
第一点是您的数据中有太多NA
。如果你想调查它。
如果我理解正确,你需要连续0的计数,然后是连续的非零,零,非零等。每个日期。
当然,这可以通过rle
实现,@ mnel在评论中也提到了这一点。但是有很多捕获量。
首先,我将使用非NA条目设置数据:
flow <- read.csv("~/Downloads/sampledataflow.csv")
names(flow) <- c("Date","discharge")
flow <- flow[1:33119, ] # remove NA entries
# format Date to POSIXct to play nice with data.table
flow$Date <- as.POSIXct(flow$Date, format="%m/%d/%Y %H:%M")
接下来,我将创建一个Date
列:
flow$g1 <- as.Date(flow$Date)
最后,我更喜欢使用data.table
。所以这是使用它的解决方案。
# load package, get data as data.table and set key
require(data.table)
flow.dt <- data.table(flow)
# set key to both "Date" and "g1" (even though, just we'll use just g1)
# to make sure that the order of rows are not changed (during sort)
setkey(flow.dt, "Date", "g1")
# group by g1 and set data to TRUE/FALSE by equating to 0 and get rle lengths
out <- flow.dt[, list(duration = rle(discharge == 0)$lengths,
val = rle(discharge == 0)$values + 1), by=g1][val == 2, val := 0]
> out # just to show a few first and last entries
# g1 duration val
# 1: 2010-05-31 120 0
# 2: 2010-06-01 722 0
# 3: 2010-06-01 138 1
# 4: 2010-06-01 32 0
# 5: 2010-06-01 79 1
# ---
# 98: 2010-06-22 291 1
# 99: 2010-06-22 423 0
# 100: 2010-06-23 664 0
# 101: 2010-06-23 278 1
# 102: 2010-06-23 379 0
因此,例如,对于2010-06-01
,有722 0's
后跟138 non-zeros
,其次是32 0's
,后跟79 non-zeros
,所以上...
答案 1 :(得分:2)
我看了前两天的一小部分样本
> do.call( cbind, tapply(flow$discharge, as.Date(flow$Date), function(x) table(x > 0) ) )
2010-06-01 2010-06-02
FALSE 1223 911
TRUE 217 529 # these are the cumulative daily durations of positive flow.
你可能想要这个转置,在这种情况下t()函数应该成功。或者你可以使用rbind。
如果你想要流动的分钟数,那么这也会有效:
tapply(flow$discharge, as.Date(flow$Date), function(x) sum(x > 0, na.rm=TRUE) )
#--------
2010-06-01 2010-06-02 2010-06-03 2010-06-04 2010-06-05 2010-06-06 2010-06-07 2010-06-08
217 529 417 463 0 0 263 220
2010-06-09 2010-06-10 2010-06-11 2010-06-12 2010-06-13 2010-06-14 2010-06-15 2010-06-16
244 219 287 234 31 245 311 324
2010-06-17 2010-06-18 2010-06-19 2010-06-20 2010-06-21 2010-06-22 2010-06-23 2010-06-24
299 305 124 129 295 296 278 0
获得放电值大于零的间隔长度:
tapply(flow$discharge, as.Date(flow$Date), function(x) rle(x>0)$lengths[rle(x>0)$values] )
#--------
$`2010-06-01`
[1] 138 79
$`2010-06-02`
[1] 95 195 239
$`2010-06-03`
[1] 57 360
$`2010-06-04`
[1] 6 457
$`2010-06-05`
integer(0)
$`2010-06-06`
integer(0)
... Snipped output
如果您想查看这些持续时间的分布,您需要取消该结果。 (请记住,午夜分裂的持续时间可能会影响计数和持续时间。)如果您只想要没有日期的持续时间,请使用此:
flowrle <- rle(flow$discharge>0)
flowrle$lengths[!is.na(flowrle$values) & flowrle$values]
#----------
[1] 138 79 95 195 296 360 6 457 263 17 203 79 80 85 30 189 17 270 127 107 31 1
[23] 2 1 241 311 229 13 82 299 305 3 121 129 295 3 2 291 278