Murali.MENON at fortisinvestments.com
2009-Jun-18 16:47 UTC
[R] Replace zeroes in vector with nearest non-zero value
Folks,
If I have a vector such as the following:
x <- c(0, -1, -1, -1, 0, 0, 1, -1, 1, 0)
and I want to replace the zeroes by the nearest non-zero number to the
left, is there a more elegant way to do this than the following loop?
y <- x
for (i in 2 : length(x))
{
if (y[i] == 0) {
y[i] <- y[i - 1]
}
}
> y
[1] 0 -1 -1 -1 -1 -1 1 -1 1 1
You can see the first zero is left as is, the next two zeroes become -1,
which is the closest non-zero to the left of them, and the last zero
becomes 1.
Cheers,
Murali
jim holtman
2009-Jun-18 17:11 UTC
[R] Replace zeroes in vector with nearest non-zero value
use na.locf in zoo:> x[1] 0 -1 -1 -1 0 0 1 -1 1 0> # replace 0 with NA so na.locf works > is.na(x) <- x == 0 > x[1] NA -1 -1 -1 NA NA 1 -1 1 NA> na.locf(x, na.rm=FALSE)[1] NA -1 -1 -1 -1 -1 1 -1 1 1>You can then go back and replace NAs with 0 On Thu, Jun 18, 2009 at 12:47 PM, <Murali.MENON@fortisinvestments.com>wrote:> Folks, > > If I have a vector such as the following: > > x <- c(0, -1, -1, -1, 0, 0, 1, -1, 1, 0) > > and I want to replace the zeroes by the nearest non-zero number to the > left, is there a more elegant way to do this than the following loop? > > y <- x > for (i in 2 : length(x)) > { > if (y[i] == 0) { > y[i] <- y[i - 1] > } > } > > > y > [1] 0 -1 -1 -1 -1 -1 1 -1 1 1 > > You can see the first zero is left as is, the next two zeroes become -1, > which is the closest non-zero to the left of them, and the last zero > becomes 1. > > Cheers, > Murali > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html<http://www.r-project.org/posting-guide.html> > and provide commented, minimal, self-contained, reproducible code. >-- Jim Holtman Cincinnati, OH +1 513 646 9390 What is the problem that you are trying to solve? [[alternative HTML version deleted]]
Gabor Grothendieck
2009-Jun-18 17:14 UTC
[R] Replace zeroes in vector with nearest non-zero value
The zoo package has na.locf which replaces NAs with the last non-NA. So, first replace 0's with NA's, apply na.locf and then replace NAs with 0's.> library(zoo) > x.na <- replace(x, x == 0, NA) > x0 <- na.locf(x.na, na.rm = FALSE) > replace(x0, is.na(x0), 0)[1] 0 -1 -1 -1 -1 -1 1 1 1 1 On Thu, Jun 18, 2009 at 12:47 PM, <Murali.MENON at fortisinvestments.com> wrote:> Folks, > > If I have a vector such as the following: > > x <- c(0, -1, -1, -1, 0, 0, 1, -1, 1, 0) > > and I want to replace the zeroes by the nearest non-zero number to the > left, is there a more elegant way to do this than the following loop? > > y <- x > for (i in 2 : length(x)) > { > ? ?if (y[i] == 0) { > ? ? ? ?y[i] <- y[i - 1] > ? ?} > } > >> y > [1] ?0 -1 -1 -1 -1 -1 ?1 -1 ?1 ?1 > > You can see the first zero is left as is, the next two zeroes become -1, > which is the closest non-zero to the left of them, and the last zero > becomes 1. > > Cheers, > Murali > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
William Dunlap
2009-Jun-18 17:27 UTC
[R] Replace zeroes in vector with nearest non-zero value
approx() almost does what you want, but you have to patch up its output to account for a possible initial run of 0's in the input:> x <- c(0, -1, -1, -1, 0, 0, 1, -1, 1, 0) > y <- approx(seq_along(x)[x!=0], x[x!=0], xout=seq_along(x),method="const", f=0, rule=2)$y> y[1] -1 -1 -1 -1 -1 -1 1 -1 1 1 Doing tricks with cumsum will do it more directly: f<-function(x){ i<-cumsum(x!=0) # indices to last non-zero value in x c(x[i==0], x[x!=0][i]) # x[i==0] is initial run of 0's, x[x!=0][i] gets the rest }> rbind(x,f(x))[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] x 0 -1 -1 -1 0 0 1 -1 1 0 0 -1 -1 -1 -1 -1 1 -1 1 1 If there are NA's in x you will have to add an NA test to the x!=0 and x==0 tests or replace the NA's by 0's before doing this. Bill Dunlap TIBCO Software Inc - Spotfire Division wdunlap tibco.com> -----Original Message----- > From: r-help-bounces at r-project.org > [mailto:r-help-bounces at r-project.org] On Behalf Of > Murali.MENON at fortisinvestments.com > Sent: Thursday, June 18, 2009 9:48 AM > To: r-help at r-project.org > Subject: [R] Replace zeroes in vector with nearest non-zero value > > Folks, > > If I have a vector such as the following: > > x <- c(0, -1, -1, -1, 0, 0, 1, -1, 1, 0) > > and I want to replace the zeroes by the nearest non-zero number to the > left, is there a more elegant way to do this than the following loop? > > y <- x > for (i in 2 : length(x)) > { > if (y[i] == 0) { > y[i] <- y[i - 1] > } > } > > > y > [1] 0 -1 -1 -1 -1 -1 1 -1 1 1 > > You can see the first zero is left as is, the next two zeroes > become -1, > which is the closest non-zero to the left of them, and the last zero > becomes 1. > > Cheers, > Murali > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >