Test data Frame:
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
Using this, I would like to edit this column or make a new one which has a True at least once every third row. Meaning I would need to check the current row, if False, and if the previous two rows are False, then make it a True. Otherwise leave it as it is. Using Zoo, Dplyr, and Rollapply, I get close.
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
Essentially my issue is that it will rollapply the sum to the whole column, and then add the Trues after. Thus, we have Trues that are not necessary. So is there a way I can do this in which the True is applied before going to the next row? I assume I need to use an apply of some sort, but that is an area I'm not familiar with, and even reading the documentation I'm not sure how to do this directly.
Due to the fact that you need to update your vector on the fly to process further operations, I'd say a simple for
-loop is the way to go:
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