数据帧中第12个连续的TRUE行

时间:2016-11-18 17:29:15

标签: r loops dataframe

如何在$ 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

2 个答案:

答案 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

编辑2:更多解释

要理解滚动总和,让我们做一个小于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次为真。