R: ifelse condition & # 8594; replace with the last value for which the condition is true

Suppose I have this input:

input=data.frame(x=c(2,3,4,5,6,7), y=c(5,5,4,4,3,5))

    x   y
1   2   5
2   3   5
3   4   4
4   5   4
5   6   3
6   7   5

      

Now I want to replace the x value if y <5. In this case I want to take the last x value for which y => 5

Something like that:

attach(input)
xnew=ifelse(y < 5, "last x value for which y=> 5", x)

      

In this example, the output should look like this:

   xnew y
1   2   5
2   3   5
3   3   4
4   3   4
5   3   3
6   7   5

      

What do I need to replace "last x value for which y=> 5"

for this to work?

Thanks in advance!

+3


source to share


2 answers


I would try na.locf

from a package zoo

. Using input

from comments



input=data.frame(x=c(2,3,4,5,6,7,8,9,10,11,12), y=c(5,5,4,4,3,5,3,5,3,3,5)) 
input[input$y < 5, "x"] <- NA
library(zoo)
input$x <- na.locf(input$x)
input
#     x y
# 1   2 5
# 2   3 5
# 3   3 4
# 4   3 4
# 5   3 3
# 6   7 5
# 7   7 3
# 8   9 5
# 9   9 3
# 10  9 3
# 11 12 5

      

+3


source


indx <- input$y[tail(which(input$y <5),1)]
input$x[input$y <5] <- indx
 input
 #  x y
 #1 2 5
 #2 3 5
 #3 3 4
 #4 3 4
 #5 3 3
 #6 7 5

      

Or using data.table

 library(data.table)
 setDT(input)[y <5, x:= y[max(which(y <5))]]

      



Update

Using a new dataset:

 input=data.frame(x=c(2,3,4,5,6,7,8,9,10,11,12), y=c(5,5,4,4,3,5,3,5,3,3,5))

 indx <- which(c(0,diff(input$y<5))==1)
 indx1 <- cumsum(which(input$y <5) %in% indx)
 input$x[which(input$y <5)]<- input$x[indx-1][indx1]
  input
 #    x y
 #1   2 5
 #2   3 5
 #3   3 4
 #4   3 4
 #5   3 3
 #6   7 5
 #7   7 3
 #8   9 5
 #9   9 3
 #10  9 3
 #11 12 5

      

+3


source







All Articles