2

I am trying to clean some data and would like to replace zeros with values from the previous date. I was hoping the following code works but it doesn't

temp = c(1,2,4,5,0,0,6,7)
temp[which(temp==0)]=temp[which(temp==0)-1]

returns

1 2 4 5 5 0 6 7

instead of

1 2 4 5 5 5 6 7

Which I was hoping for. Is there a nice way of doing this without looping?

hjw
  • 1,279
  • 1
  • 11
  • 25
  • The code works perfectly. It replaces the zero values by the preceding value. In your case that happens to be 0. You need to rethink you strategy for special cases, such as the one at hand. I would suggest you the function `rle`. – Roman Luštrik Jul 11 '13 at 11:20
  • possible duplicate of [How to copy a value in a vector to next position(s) in vector](http://stackoverflow.com/questions/17320312/how-to-copy-a-value-in-a-vector-to-next-positions-in-vector) – QuantIbex Jul 11 '13 at 11:24

2 Answers2

6

The operation is called "Last Observation Carried Forward" and usually used to fill data gaps. It's a common operation for time series and thus implemented in package zoo:

temp = c(1,2,4,5,0,0,6,7)

temp[temp==0] <- NA

library(zoo)
na.locf(temp)
#[1] 1 2 4 5 5 5 6 7
Roland
  • 127,288
  • 10
  • 191
  • 288
2

You could use essentially your same logic except you'll want to apply it to the values vector that results from using rle

temp = c(1,2,4,5,0,0,6,0)

o <- rle(temp)
o$values[o$values == 0] <- o$values[which(o$values == 0) - 1]
inverse.rle(o)
#[1] 1 2 4 5 5 5 6 6
Dason
  • 60,663
  • 9
  • 131
  • 148