tags:

views:

56

answers:

2

I have vectors with mostly NA entries. I want to replace every NA with that vector's preceding non-NA entry. Specifically, the first entry will always be a 1, followed by a bunch of NAs, which I want to replace with 1. The ith entry could be another numeric, let's say 2, followed by more NAs that I want to replace with 2. And so on. The loop below achieves this, but there has to be a more R way to do it, right? I wanted to vectorize with ifelse(), but I couldn't figure out how to replace the ith entry with the i-1th entry.

> vec <- rep(NA, 10)
> vec
 [1] NA NA NA NA NA NA NA NA NA NA
> vec[1] <- 1; vec[4] <- 2; vec[7] <- 3
> vec
 [1]  1 NA NA  2 NA NA  3 NA NA NA
> for (i in 1:length(vec)) if (is.na(vec[i])) vec[i] <- vec[i-1]
> vec
 [1] 1 1 1 2 2 2 3 3 3 3

Thanks!

If context helps, I am adjusting for stock splits from the WRDS database, which has a column that shows when and how a split occurs.

+5  A: 

This is already implemented in package zoo, function na.locf (Last Observation Carried Forward). See also here: Propagating data within a vector

rcs
Thanks! (half the time the answer is already here... I just need to search the correct phrase)
richardh
+1  A: 

If you're adjusting for stock splits, maybe you could use adjRatios from the TTR package. All the heavy lifting in done in C, so it is very fast. See adjustOHLC for an example of how to use adjRatios to adjust your data.

> require(quantmod)
> getSymbols("IBM",from="1980-01-01")
[1] "IBM"
> spl <- getSplits("IBM",from="1980-01-01")
> div <- getDividends("IBM",from="1980-01-01")
> 
> head(spl)
           IBM.spl
1997-05-28     0.5
1999-05-27     0.5
> head(div)
            [,1]
1980-02-06 0.215
1980-05-08 0.215
1980-08-07 0.215
1980-11-05 0.215
1981-02-05 0.215
1981-05-07 0.215
> 
> adjusters <- adjRatios(spl, div, Cl(IBM))
> head(adjusters)
           Split       Div
1980-01-02  0.25 0.7510967
1980-01-03  0.25 0.7510967
1980-01-04  0.25 0.7510967
1980-01-07  0.25 0.7510967
1980-01-08  0.25 0.7510967
1980-01-09  0.25 0.7510967
Joshua Ulrich