Reputation: 79
I am trying to replicate a simple drag function in Excel into R.
Basically I want to create an ifelse that takes into account the value of each previous row in the SAME column that's being created (i.e. dynamically)
Here is a reproducible example
library(dplyr)
x <- c(1,1,1,15,1,1,1,24,1,1,1)
df <- data.frame(x)
df$y <- 1
df$y <- ifelse(df$x == 1, lag(df$y), lag(df$y)+1)
Here is the unwanted output
x y
1 NA
1 1
1 1
15 2
1 1
1 1
1 1
24 2
1 1
1 1
1 1
The above code changes y only when x > 1 and I want to keep that y+1 to the next rows until we find another x that is > 1.
The desired output of y should be something like this
desired y
NA
1
1
2
2
2
2
3
3
3
3
Upvotes: 1
Views: 877
Reputation: 388797
You can use Reduce
with accumulate = TRUE
.
df$y <- Reduce(`+`, df$x > 1, accumulate = TRUE) + 1
df
# x y
#1 1 1
#2 1 1
#3 1 1
#4 15 2
#5 1 2
#6 1 2
#7 1 2
#8 24 3
#9 1 3
#10 1 3
#11 1 3
If you want a tidyverse
answer you can look into accumulate
.
library(dplyr)
library(purrr)
df %>% mutate(y = accumulate(x > 1, `+`) + 1)
Upvotes: 1
Reputation: 24770
How about cumsum
:
df$y <- cumsum(df$x != 1) + 1
df
x y
1 1 1
2 1 1
3 1 1
4 15 2
5 1 2
6 1 2
7 1 2
8 24 3
9 1 3
10 1 3
For something more generalizable, you might try a for
loop.
for(i in seq_along(df$x)) df$y[i] <- ifelse(df$x[i]==1,
sum(df$y[i-1],0,na.rm = TRUE),
sum(df$y[i-1],1,na.rm = TRUE))
Upvotes: 2