Data
DIp DIn
1 12 11
2 25 25
3 14 23
4 17 28
5 23 17
6 25 16
7 34 21
8 31 19
9 27 17
10 25 20
11 15 16
12 16 17
13 19 21
14 21 21
dput
structure(list(DIp = c(12L, 25L, 14L, 17L, 23L, 25L, 34L, 31L,
27L, 25L, 15L, 16L, 19L, 21L), DIn = c(11L, 25L, 23L, 28L, 17L,
16L, 21L, 19L, 17L, 20L, 16L, 17L, 21L, 21L)), row.names = c(NA,
-14L), class = "data.frame")
I want my code to do the following -
If DIp > DIn for at least 10 consecutive rows - mark all the following as Uptrend. Else, mark as Undetermined.
I am trying to do this but I don't know how to break the loop for every 10 consecutive rows- i.e if DIp[1:10] > DIn[1:10], then, return new column 'MC' with 'Uptrend' for all rows where the condition is met.
CodePudding user response:
I think you need a rolling operation. There are lot of packages in R which help you perform such calculation.
Here's one with zoo's rollaplly -
library(dplyr)
library(zoo)
df <- df %>% mutate(result = rollapplyr(DIp > DIn, 10, all, fill = FALSE))
result would have TRUE/FALSE values. If there are at least 10 consective rows where DIp > DIn then it should return TRUE or else FALSE.
If you want output as text "Uptrend" and "Undetermined" you may use an ifelse.
df <- df %>%
mutate(result = ifelse(rollapplyr(DIp > DIn, 10, all, fill = FALSE),
"Uptrend", "Undetermined"))
CodePudding user response:
You can also do this in base R
rleid <- rle(df$DIp > df$DIn)
rleid$values <- rleid$lengths > 9L & rleid$values
df$MC <- c("Undetermined", "Uptrend")[inverse.rle(rleid) 1L]
rle gives you the number of consecutive TRUE/FALSE. TRUE means DIp > DIn. Then we recode the rle values only if the number of consecutive TRUEs is greater than 10. Last, we inverse the rle to get back the vector and map TRUE/FALSE to "Uptrend"/"Undetermined".
Output
> df
DIp DIn MC
1 12 11 Undetermined
2 25 25 Undetermined
3 14 23 Undetermined
4 17 28 Undetermined
5 23 17 Undetermined
6 25 16 Undetermined
7 34 21 Undetermined
8 31 19 Undetermined
9 27 17 Undetermined
10 25 20 Undetermined
11 15 16 Undetermined
12 16 17 Undetermined
13 19 21 Undetermined
14 21 21 Undetermined
An example of rle:
> rle(c(T,T,T,F,F))
Run Length Encoding
lengths: int [1:2] 3 2
values : logi [1:2] TRUE FALSE
> inverse.rle(rle(c(T,T,T,F,F)))
[1] TRUE TRUE TRUE FALSE FALSE
