wen
wen

Reputation: 1935

How to fill in the "succeeding" numbers whenever there is a 0 in R?

I have a string of numbers:

n1 = c(1, 1, 0, 6, 0, 0, 10, 10, 11, 12, 0, 0, 19, 23, 0, 0)

I need to replace 0 with the corresponding number right "behind" it to get, while leaving the 0s in the tail alone (cause there is nothing right behind them):

n2 = c(1, 1, 6, 6, 10, 10, 10, 10, 11, 12, 19, 19, 19, 23, 0, 0)

How can I get from n1 to n2?

This seems to be a much harder question than the one I've asked earlier:

How to fill in the preceding numbers whenever there is a 0 in R?

where flodel has come up with an elegant solution:

n2 <- n1[cummax(seq_along(n1) * (n1 != 0))]

However, this solution does not work here; I've tried but failed to adapt the code.

Can someone else figure out an elegant solution?

Thanks in advance!

Upvotes: 0

Views: 133

Answers (3)

MrFlick
MrFlick

Reputation: 206253

You can use flodel's suggestion in reverse

na = c(1, 1, 0, 6, 0, 0, 10, 10, 11, 12, 0, 0, 19, 23, 0, 0)
locf<-function(x) {
    x<-rev(x)
    a<-x[cummax(seq_along(x) * (x != 0))]
    c(rev(a), rep(0, length(x)-length(a)))
}
locf(na)
# [1]  1  1  6  6 10 10 10 10 11 12 19 19 19 23  0  0

Upvotes: 2

Tyler Rinker
Tyler Rinker

Reputation: 109874

Here's a rle approach:

out <- rle(n1)

locs <- out$values == 0 & !seq_along(out$values) %in% length(out$values)
out$values[locs] <- out$values[which(locs) + 1]
with(out, rep(values, lengths))

##  [1]  1  1  6  6 10 10 10 10 11 12 19 19 19 23  0  0

Upvotes: 2

Matthew Lundberg
Matthew Lundberg

Reputation: 42669

If you don't also have NA in the vector, you can use na.locf from package zoo:

n1[n1==0] <- NA
n2 = na.locf(n1, na.rm=FALSE, fromLast=TRUE)
n2[is.na(n2)] <- 0
n2
## [1]  1  1  6  6 10 10 10 10 11 12 19 19 19 23  0  0

Upvotes: 5

Related Questions