R - 根据前几行每第 n 行插入一个 True

R - Insert a True every nth row based on previous rows

测试数据帧:

a<-data.frame(True_False = c(T,F,F,F,F,T,F,T,T,T,F,F,F,F,F,F,F,F))
  True_False
1        TRUE
2       FALSE
3       FALSE
4       FALSE
5       FALSE
6        TRUE
7       FALSE
8        TRUE
9        TRUE
10       TRUE
11      FALSE
12      FALSE
13      FALSE
14      FALSE
15      FALSE
16      FALSE
17      FALSE
18      FALSE

使用它,我想编辑此列或创建一个新列,其中至少每三行一次为 True。这意味着我需要检查当前行,如果为 False,如果前两行为 False,则将其设置为 True。否则保持原样。使用 Zoo、Dplyr 和 Rollapply,我接近了。

library(zoo)
library(tidyverse)
    b<-a%>%
  mutate(Roll = ifelse(rollapplyr(Input,3,sum, partial = T) == 0,T,Input))
b$Desired<-c(T,F,F,T,F,T,F,T,T,T,F,F,T,F,F,T,F,F)

   Input  Roll Desired
1   TRUE  TRUE    TRUE
2  FALSE FALSE   FALSE
3  FALSE FALSE   FALSE
4  FALSE  TRUE    TRUE
5  FALSE  TRUE   FALSE
6   TRUE  TRUE    TRUE
7  FALSE FALSE   FALSE
8   TRUE  TRUE    TRUE
9   TRUE  TRUE    TRUE
10  TRUE  TRUE    TRUE
11 FALSE FALSE   FALSE
12 FALSE FALSE   FALSE
13 FALSE  TRUE    TRUE
14 FALSE  TRUE   FALSE
15 FALSE  TRUE   FALSE
16 FALSE  TRUE    TRUE
17 FALSE  TRUE   FALSE
18 FALSE  TRUE   FALSE

基本上我的问题是它会将总和滚动应用到整列,然后添加 Trues。因此,我们有不必要的真值。那么有没有一种方法可以做到这一点,在进入下一行之前应用 True ?我假设我需要使用某种应用,但这是我不熟悉的领域,即使阅读文档我也不确定如何直接执行此操作。

看来您需要这样的东西。这是一种方法(不是最干净的):

a<-data.frame(True_False = c(T,F,F,F,F,T,F,T,T,T,F,F,F,F,F,F,F,F))
a$Desired<-NA
a$Desired[4:nrow(a)]<-sapply(4:nrow(a),function(z){
  if(z%%3==1 & a$True_False[z]==F & a$True_False[z-1]==F & a$True_False[z-2]==F){a$True_False[z]<-T}else{a$True_False[z]}
})
a$Desired[1:3]<-a$True_False[1:3]

由于您需要动态更新向量以处理进一步的操作,我想说一个简单的 for 循环是可行的方法:

for(i in 3:nrow(a)){
  a$True_False[i] <- ifelse(sum(a$True_False[(i-2):i]) == 0, T, a$True_False[i])
}

> a
   True_False
1        TRUE
2       FALSE
3       FALSE
4        TRUE
5       FALSE
6        TRUE
7       FALSE
8        TRUE
9        TRUE
10       TRUE
11      FALSE
12      FALSE
13       TRUE
14      FALSE
15      FALSE
16       TRUE
17      FALSE
18      FALSE

通过Reduce定义一个更新函数f和运行。

f <- function(x, i) {
  if (i >= 3 && all(!x[seq(to = i, length = 3)])) x[i] <- TRUE
  x
}
transform(a, new = Reduce(f, init = True_False, seq_along(True_False)))

给予:

   True_False   new
1        TRUE  TRUE
2       FALSE FALSE
3       FALSE FALSE
4       FALSE  TRUE
5       FALSE FALSE
6        TRUE  TRUE
7       FALSE FALSE
8        TRUE  TRUE
9        TRUE  TRUE
10       TRUE  TRUE
11      FALSE FALSE
12      FALSE FALSE
13      FALSE  TRUE
14      FALSE FALSE
15      FALSE FALSE
16      FALSE  TRUE
17      FALSE FALSE
18      FALSE FALSE