tags:

views:

69

answers:

4

I have a vector of values which include NAs. The values need to be processed by an external program that can't handle NAs, so they are stripped out, its written to a file, processed, then read back in, resulting in a vector of the length of the number of non-NAs. Example, suppose the input is 7 3 4 NA 5 4 6 NA 1 NA, then the output would just be 7 values. What I need to do is re-insert the NAs in position.

So, given two vectors X and Y:

 > X
 [1]  64   1   9 100  16  NA  25  NA   4  49  36  NA  81
 > Y
 [1]  8  1  3 10  4  5  2  7  6  9

produce:

8 1 3 10 4 NA 5 NA 2 7 6 NA 9

(you may notice that X is Y^2, thats just for an example).

I could knock out a function to do this but I wonder if there's any nice tricksy ways of doing it... split, list, length... hmmm...

+1  A: 

Answering my own question is probably very bad form, but I think this is probably about the neatest:

rena <- function(X,Z){
Y=rep(NA,length(X))
Y[!is.na(X)]=Z    
Y
}
Spacedman
Could be shortened to `function(X,Z) {X[!is.na(X)]<-Z;X}`.
Marek
+3  A: 

na.omit keeps an attribute of the locations of the NA in the original series, so you could use that to know where to put the missing values:

Y <- sqrt(na.omit(X))
Z <- rep(NA,length(Y)+length(attr(Y,"na.action")))
Z[-attr(Y,"na.action")] <- Y
#> Z
# [1]  8  1  3 10  4 NA  5 NA  2  7  6 NA  9
Joshua Ulrich
+1  A: 

Another variant on the same theme

rena <- function(X,Z){
    X[which(!is.na(X))]=Z    
    X
}

R automatically fills the rest with NA.

Edit: Corrected by Marek.

Joris Meys
Wrong: `rena(c(1,2,NA),c(10,20))`. Why bother with `Y`, use `X` as is my comment to Spacedman answer.
Marek
@marek: good catch. Thx for the correction.
Joris Meys
+2  A: 

Can also try replace:

replace(X, !is.na(X), Y)
Charles
+1 cleanest solution so far.
Joris Meys