在R中查找非零值和这些值的频率

在R中查找非零值和这些值的频率,r,R,我有一个数据,它有两个参数,它们是数据/时间和流量。流量数据为间歇性流量。假设有时流量为零,突然流量开始,有一段时间会出现非零值,然后流量再次为零。我想了解非零值何时出现,以及每个非零值流持续多长时间。我已将样本数据集附加到此位置 数据为1分钟数据 我能够将数据导入R,如下所示: flow <- read.csv("sampledataflow.csv") summary(flow) names(flow) <- c("Date","discharge") flow$Date

我有一个数据,它有两个参数,它们是数据/时间和流量。流量数据为间歇性流量。假设有时流量为零,突然流量开始,有一段时间会出现非零值,然后流量再次为零。我想了解非零值何时出现,以及每个非零值流持续多长时间。我已将样本数据集附加到此位置

数据为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
如果我不清楚,请告诉我。谢谢

其他信息:


我认为我们需要首先检查非零值,然后在它再次达到零值之前,找出有多少个非零值连续存在。我想了解的是流释放持续时间。例如,在一天内可能会有多个版本,我想记下发布是在什么时候开始的,在值为零之前它持续了多长时间。我希望这能更好地解释这个问题

我看了前两天的一个小样本

> 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
flowrle 0)
flowrle$长度[!is.na(flowrle$值)&flowrle$值]
#----------
[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

第一点是,您的数据中有太多的
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")
最后,我更喜欢使用
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
#加载包,获取数据作为data.table并设置键
要求(数据表)

使用
rle
的flow.dt运行长度编码?例如
rle(流量$流量)
?您的数据仅包含33k个奇数值。其余的只有
Timestamp=”“
flow=NA
Arun,这只是一个示例,我还没有上传所有数据。事实上,我有大约230k的数据。我已经在我原来的帖子上添加了更多的信息。嗨,德温,谢谢你的回答。但我似乎没有把我的问题解释清楚。我们需要首先检查非零值,然后在它再次达到零值之前,找出连续存在多少非零值。我想你展示的结果是每天非零分钟。我想了解的是流释放持续时间。例如,在一天内可能会有多个版本,我想记下发布是在什么时候开始的,在值为零之前它持续了多长时间。我希望这能更好地解释这个问题。这很容易提供。你只需要做好每天处理不规则数字的准备。德温,非常感谢你更新的答案。我想知道是否有可能在您计算的时间间隔长度内输出平均非零排放值?该功能是
mean
,并且考虑到NAs的数量,您最好使用
na.rm=TRUE
选项。(下次请构建一个更小的数据集。)@Arun:非常感谢你的回答。是的,找到每个零和非零的持续时间确实解决了我的问题。如果可能的话,另一个不错的加法是这些持续时间内的零和非零的平均值。谢谢。我想这回答了你的问题。获得平均值很简单,我将把它留给你。
# 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