Reputation: 1935
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
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
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
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