Inserting removed data back into a vector, at its original location, in R

Viewed 31

In R, I have a vector, and I want to remove certain elements, apply a computation to that filtered array, and then insert the removed elements back in again.

For example, if I want to remove NaNs, and then apply cumsum:

> v = c(1, NaN, 2, NaN, 3)
> (nans = is.nan(v))
[1] FALSE  TRUE FALSE  TRUE FALSE
> (filtered = v[!nans])
[1] 1 2 3
> (summed = cumsum(filtered))
[1] 1 3 6

Now, what I want is to insert the NaNs back into the vector in their original locations, giving me c(1, NaN, 3, NaN, 6).

The naive way to do this is:

> summed[nans] = v[nans]
> summed
[1]   1 NaN   6 NaN  NA

However obviously this is wrong. Because the indicies of summed are different to v, I can't simply re-use the nans logical vector.

Note that this is just a simplified example. In my real problem, the removed values aren't all the same as each other (NaN), and I also don't know how many values will be removed nor how long v is.

So my question is, how can I reverse the original logical indexing I did when I filtered the vector, and get back the processed array, but with NaNs inserted again? I'm happy with any core R or library solution.

2 Answers

Use :

v[!nans] = summed
v
#[1]   1 NaN   3 NaN   6

!nans reverses the boolean vector giving the index where value is not NaN and summed is the vector to replace.

You can use [<- to reinsert NaN:

"[<-"(rep(NaN, length(v)), !nans, summed)
#[1]   1 NaN   3 NaN   6

In fact here I create a vector of NaN and insert the values of summed.

Alternatively the NaN from v could be used like:

"[<-"(v, !nans, summed)
#[1]   1 NaN   3 NaN   6
Related