Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I can't think of an obvious simple solution, but, having looked at the suggestions (particularly <a href="https://stackoverflow.com/users/202229/smci">smci</a>'s suggestion of using <code>rle</code>) I came up with a complicated function that appears to be more efficient.</p> <p>This is the code, I'll explain below:</p> <pre><code># Your function your.func = function(dat) { na.pos &lt;- which(is.na(dat)) if (length(na.pos) == length(dat)) { return(dat) } non.na.pos &lt;- setdiff(seq_along(dat), na.pos) nearest.non.na.pos &lt;- sapply(na.pos, function(x) which.min(abs(non.na.pos - x))) dat[na.pos] &lt;- dat[non.na.pos[nearest.non.na.pos]] dat } # My function my.func = function(dat) { nas=is.na(dat) if (!any(!nas)) return (dat) t=rle(nas) f=sapply(t$lengths[t$values],seq) a=unlist(f) b=unlist(lapply(f,rev)) x=which(nas) l=length(dat) dat[nas]=ifelse(a&gt;b,dat[ ifelse((x+b)&gt;l,x-a,x+b) ],dat[ifelse((x-a)&lt;1,x+b,x-a)]) dat } # Test n = 100000 test.vec = 1:n set.seed(1) test.vec[sample(test.vec,n/4)]=NA system.time(t1&lt;-my.func(test.vec)) system.time(t2&lt;-your.func(test.vec)) # 10 times speed improvement on my machine # Verify any(t1!=t2) </code></pre> <p>My function relies on <code>rle</code>. I am reading the comments above but it looks to me like <code>rle</code> works just fine for <code>NA</code>. It is easiest to explain with a small example.</p> <p>If I start with a vector:</p> <pre><code>dat=c(1,2,3,4,NA,NA,NA,8,NA,10,11,12,NA,NA,NA,NA,NA,18) </code></pre> <p>I then get the positions of all the NAs:</p> <pre><code>x=c(5,6,7,8,13,14,15,16,17) </code></pre> <p>Then, for every "run" of NAs I create a sequence from 1 to the length of the run:</p> <pre><code>a=c(1,2,3,1,1,2,3,4,5) </code></pre> <p>Then I do it again, but I reverse the sequence:</p> <pre><code>b=c(3,2,1,1,5,4,3,2,1) </code></pre> <p>Now, I can just compare vectors a and b: If a&lt;=b then look back and grab the value at x-a. If a>b then look ahead and grab the value at x+b. The rest is just handling the corner cases when you have all NAs or NA runs at the end or the start of the vector.</p> <p>There is probably a better, simpler, solution, but I hope this gets you started.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload