如何在$ crit中找到第12个连续的TRUE值?我正在尝试这样的事情:
for(i in 12:nrow(df)) {
if(sum(df$crit[(i-12):i])=12)
print(df$date[i])
}
此代码是否可以循环连续12行的组?
我的数据:
date rain temp rh accumulation crit
1 2015-04-02 10:00:00 0.5 9.8 96 NA FALSE
2 2015-04-02 11:00:00 0.1 10.0 95 NA TRUE
3 2015-04-02 12:00:00 0.0 10.1 95 NA TRUE
4 2015-04-02 13:00:00 0.1 10.7 95 NA TRUE
5 2015-04-02 14:00:00 0.0 10.7 94 NA TRUE
6 2015-04-02 15:00:00 0.1 10.7 95 NA TRUE
7 2015-04-02 16:00:00 0.6 11.2 96 NA TRUE
8 2015-04-02 17:00:00 0.1 11.7 96 NA TRUE
9 2015-04-02 18:00:00 0.4 11.6 96 NA TRUE
10 2015-04-02 19:00:00 0.2 11.3 96 NA TRUE
11 2015-04-02 20:00:00 0.6 11.3 97 NA TRUE
12 2015-04-02 21:00:00 0.2 11.6 97 NA TRUE
13 2015-04-02 22:00:00 0.0 12.0 96 1 TRUE
14 2015-04-02 23:00:00 0.3 11.8 96 2 TRUE
15 2015-04-03 00:00:00 0.0 11.8 97 3 TRUE
16 2015-04-03 01:00:00 0.0 11.9 97 4 TRUE
17 2015-04-03 02:00:00 0.1 12.2 95 5 TRUE
18 2015-04-03 03:00:00 0.8 11.4 93 6 TRUE
19 2015-04-03 04:00:00 0.6 10.9 92 7 TRUE
20 2015-04-03 05:00:00 0.0 10.3 89 NA FALSE
答案 0 :(得分:2)
听起来像一个滚动的总和 - 你想要加上最后12个crit
值,看看你是否得到12。有很多方法可以实现滚动总和,但实现起来特别容易的是滞后cumsum
。
## some data
set.seed(47)
crit = runif(100) < 0.8
## rolling sum of last 12 elements
rs = cumsum(crit) - cumsum(c(rep(0, 12), head(crit, -12)))
## see where we get to 12
which(rs == 12)
# [1] 28 29 30 31 32 33 34 62 63 64 65 66
## verify
names(crit) = seq_along(crit)
crit[16:29]
# 16 17 18 19 20 21 22 23 24 25 26 27 28 29
# FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
希望代码很容易理解。在验证步骤中,我们可以看到第28个元素(which
的第一个输出)确实是12个TRUE
系列中的第12个元素。
转换为数据框应用程序:
set.seed(47)
dd = data.frame(crit = runif(100) < 0.8, date = as.Date("2016-01-01") + seq_along(crit))
rs = with(dd, cumsum(crit) - cumsum(c(rep(0, 12), head(crit, -12))))
dd[which(rs == 12), ]
# crit date
# 28 TRUE 2016-01-29
# 29 TRUE 2016-01-30
# 30 TRUE 2016-01-31
# 31 TRUE 2016-02-01
# 32 TRUE 2016-02-02
# 33 TRUE 2016-02-03
# 34 TRUE 2016-02-04
# 62 TRUE 2016-03-03
# 63 TRUE 2016-03-04
# 64 TRUE 2016-03-05
# 65 TRUE 2016-03-06
# 66 TRUE 2016-03-07
要理解滚动总和,让我们做一个小于12的简单例子 - 说我们想知道最后3个元素的总和。你的数据已经非常简单,因为我们总结的列只有TRUE和FALSE,但是为了打印的简短,我会使用1和0。
ex = c(1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1)
cumsum
函数给出了到目前为止所有元素的累积和。我们可以将i
的{{1}}元素视为cumsum(ex)
c_ex[i] = sum(ex[1:i])
滚动总和就像累积总和一样,但是我们不希望在向量结束之前保留所有内容,只是最后几个元素。如果我们有(c_ex = cumsum(ex))
# [1] 1 1 2 3 3 3 4 5 6 6 7 8 9 10
,ex
的3个元素的滚动总和,我们可以将rs_ex
元素写为i
。这与您在问题中的代码中的内容非常相似(尽管请注意rs_ex[i] = sum(ex[(i - 2):i])
制作三个元素,因此我们确实希望以i-2, i-1, i
开头,查看大小为i - (n - 1)
的窗口
由于加法很好地交换,我们可以分解滚动总和并将其重写为n
。换句话说,如果我们想知道元素8,9和10的总和,并且我们已经知道累积和,我们可以得到元素1到10的累积和,并减去元素1到7的累积和。什么是left是元素8,9和10的总和。
为了与原始数据很好地对齐,我们创建了一个与原始向量相同的虚拟向量,但前面粘有rs_ex[i] = sum(ex[1:i]) - sum(ex[1:(i - 3)])
个零(并且最后n
个元素被截断结束),n
我们可以减去原始的cumsum
来获得滚动总和。
cumsum
这给了我们最后三个元素的滚动总和。
回到原始示例,如果您需要使用这么多,只需将其添加到您的数据中即可。如果您的数据框名为# add three 0s at front, chop off last three elements
rs_ex = cumsum(ex) - cumsum( c(rep(0, 3), head(ex, -3)))
# [1] 1 1 2 2 2 1 1 2 3 2 2 2 3 3
,请执行
dd
然后,您可以使用滚动和信息继续使用数据框,例如,
dd$rs = with(dd, cumsum(crit) - cumsum(c(rep(0, 12), head(crit, -12))))
查看最后11个值和subset(dd, rs == 12)
的当前值均为crit
的所有行。如果您需要TRUE
行中的所有行+/- 3,那么找到它们的一种方法是
rs == 12
可能有更好,更通用的方法,但这应该适用于像3这样的小窗口。
答案 1 :(得分:0)
假设你有暴击:
crit<- c(FALSE, rep(TRUE,12),FALSE, TRUE, FALSE,rep(TRUE,12))
> crit
[1] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE FALSE
[17] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
如果检查前12个值,包括1个False和11个TRUE,则得到:
> x <- rle(crit[1:12])
> x
Run Length Encoding
lengths: int [1:2] 1 11
values : logi [1:2] FALSE TRUE
如果你从2:13开始检查,这些都是正确的,你得到:
> x
Run Length Encoding
lengths: int 12
values : logi TRUE
然后如果你检查是否都是真的,你可以使用mean:
进行如下检查> mean(x$values==TRUE)
[1] 1
所以如果你打算检查1:12,13:24,开始:结束......等等。你可以查一下:
x <- rle(crit[start:end])
然后
mean(x$values==TRUE)
如果等于1,则确认您连续12次为真。