Reputation: 1469
I have this time series as
Quant1 Quant2
2013-01-23 400 200
2013-01-22 0 0
2013-01-21 0 0
2013-01-20 125 100
2013-01-18 120 0
And wants output as
Quant1 Quant2
2013-01-23 400 200
2013-01-22 125 100
2013-01-21 125 100
2013-01-20 125 100
2013-01-18 120 0
I am trying this, but it does not seem to work. I am getting null error NULL Warning encountered while processing method
replace(df,df == 0, NA)
df <- na.locf(df)
df[is.na(df)] <- 0
Any suggestions?
Update
As per most voted answer I tried (I modified input dates)
> z <- structure(c(400L, 0L, 0L, 125L, 120L, 200L, 0L, 0L, 100L,
+ 0L), .Dim = c(5L, 2L), .Dimnames = list(NULL, c("Quant1", "Quant2"
+ )), index = structure(c(15728, 15727, 15726, 15725, 15723), class = "Date"),
+ class = "zoo")
> z
Quant1 Quant2
2013-01-23 400 200
2013-01-22 0 0
2013-01-21 0 0
2013-01-20 125 100
2013-01-18 120 0
> L <- rowSums(z != 0) > 0
> z[] <- coredata(z)[which(L)[cumsum(L)],]
> z
Quant1 Quant2
2013-01-23 400 200
2013-01-22 0 0
2013-01-21 0 0
2013-01-20 0 0
2013-01-18 120 0
Upvotes: 0
Views: 1308
Reputation: 270020
In the future please make your questions self-contained including the library calls and dput(x)
output of any input x
.
We assume this is a zoo object as shown at the end. We will call it z since df suggests that its a data frame.
library(zoo)
L <- rowSums(z != 0) > 0
z[] <- coredata(z)[which(L)[cumsum(L)],]
giving:
> z
Quant1 Quant2
2013-01-18 400 200
2013-01-20 400 200
2013-01-21 400 200
2013-01-22 125 100
2013-01-23 120 0
Note: This input was used:
z <- structure(c(400L, 400L, 400L, 125L, 120L, 200L, 200L, 200L, 100L,
0L), .Dim = c(5L, 2L), .Dimnames = list(NULL, c("Quant1", "Quant2"
)), index = structure(c(15723, 15725, 15726, 15727, 15728), class = "Date"),
class = "zoo")
Upvotes: 4
Reputation: 515
I also assumed it to be a zoo-object and build the following function by hand which only cares about Quant1 to be zero or not. It is less elegant and probably slower (one should replace the for loop by some apply-function) than the previous approach by Grothendieck but maybe is somewhat instructive to you.
require(zoo)
times <- as.POSIXct(c("2013-01-18", "2013-01-20", "2013-01-21", "2013-01-22", "2013-01-23", "2013-01-25", "2013-01-29", "2013-02-02", "2013-02-04"))
quant1 <- c(400,0,0,125,120,0,70,0,0)
quant2 <- c(200,0,0,100,0,300,150,80, 200)
z <- zoo(data.frame(Quant1 = quant1, Quant2 = quant2), order.by = times)
repl_zeros <- function (z) {
diffs <- c(0, diff(as.numeric(z$Quant1 == 0)))
beginnings <- which(diffs == 1)
ends <- which(diffs == -1) - 1
valueindices <- ends + 1
for (i in 1:length(valueindices)) {
z[beginnings[i]:ends[i],]$Quant1 <- z[valueindices[i],]$Quant1
z[beginnings[i]:ends[i],]$Quant2 <- z[valueindices[i],]$Quant2
}
z
}
Note: repl_zeros replaces zeros by following values as in your example, where you said you want to replace by previous values in the title of your question. Adjusting it to what you really meant should be easy though.
Upvotes: 0