title: How do I prevent interpolation between values where there are more than X number of missing rows of data?
body: <p>I would like to interpolate missing data, but skip scenarios where there are more than X number (e.g., 3) missing rows of data. I have code below, but the final step does not work.</p>
  
  <p>I previously posted a question and got a great answer (<a href="https://stackoverflow.com/questions/55599319/how-do-i-prevent-interpolation-between-values-where-there-are-more-than-2-missin/55603949?noredirect=1#comment98070872_55603949">How do I prevent interpolation between values where there are more than 2 missing rows of data?</a>). However, I oversimplified the example dataframe, and now when I try to run the code, I get this error in the final step:</p>
  
  <pre><code>Error in `[&lt;-.data.frame`(`*tmp*`, m_NA, value = NA) : unsupported matrix index in replacement
  </code></pre>
  
  <p>Is there a simple way to adjust the code below to deal with this? Or is there a better solution?</p>
  
  <p>Here is a subset of my data:</p>
  
  <pre><code>alldata &lt;- structure(list(q_cms = c(0.157, 0.154, 0.154, 0.151, 0.144, 0.151, 
  0.151, 0.154, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
  NA, NA, 0.157, 0.144, NA), site = c("Wade", "Wade", "Wade", "Wade", 
  "Wade", "Wade", "Wade", "Wade", "Wade", "Wade", "Wade", "Wade", 
  "Wade", "Wade", "Wade", "Wade", "Wade", "Wade", "Wade", "Wade", 
  "Wade", "Wade", "Wade", "Wade", "Wade"), r_timestamp = structure(c(1479691800, 
  1479692700, 1479693600, 1479694500, 1479695400, 1479696300, 1479697200, 
  1479698100, 1479698160, 1479698220, 1479698280, 1479698340, 1479698400, 
  1479698460, 1479698520, 1479698580, 1479698640, 1479698700, 1479698760, 
  1479698820, 1479698880, 1479698940, 1479699000, 1479699900, 1479699960
  ), class = c("POSIXct", "POSIXt"), tzone = "Etc/GMT-4"), NO3_mgNL = c(0.0351, 
  NA, NA, NA, NA, NA, NA, NA, 0.0316, 0.0309, 0.0309, 0.03, 0.029, 
  0.0297, 0.0278, 0.0278, 0.0304, 0.0292, 0.0267, 0.0282, 0.0293, 
  0.0313, 0.0306, NA, 0.0311), DOC_mgL = c(1.854, NA, NA, NA, NA, 
  NA, NA, NA, 1.85, 1.843, 1.836, 1.822, 1.802, 1.836, 1.797, 1.808, 
  1.817, 1.815, 1.813, 1.813, 1.824, 1.826, 1.82, NA, 1.831)), class = c("tbl_df", 
  "tbl", "data.frame"), row.names = c(NA, -25L))
  </code></pre>
  
  <p>And here is the code I am trying to execute. In this example, I am trying to skip interpolation where there are 3 or more consecutive missing rows of data:</p>
  
  <p>Packages required:</p>
  
  <pre><code>library('tidyverse')
  library('lubridate')
  </code></pre>
  
  <p>Step 1: Create a function, consecutiveNA, that can identify the consecutive NA in a vector based on a threshold (specified by the argument len):</p>
  
  <pre><code>consecutiveNA &lt;- function(x, len = 3){
    rl &lt;- rle(is.na(x))
    logi &lt;- rl$lengths &gt;= len &amp; rl$values
    rl$values &lt;- logi
    inver &lt;- inverse.rle(rl)
    return(inver)
  }
  </code></pre>
  
  <p>Step 2: Apply the approx function to target columns (interpolate NAs using linear interpolation):</p>
  
  <pre><code>alldata_int &lt;- alldata %&gt;%
    arrange(site, r_timestamp) %&gt;%
    group_by(site, year(r_timestamp)) %&gt;%
    mutate_at(vars(c(NO3_mgNL, DOC_mgL)),
              funs(approx(r_timestamp, ., r_timestamp, rule=1, method="linear")[["y"]]))
  </code></pre>
  
  <p>Step 3: Apply the consecutiveNA function to all columns in alldata and convert the result to a matrix:</p>
  
  <pre><code>m_NA &lt;- map(alldata, consecutiveNA, len = 3) %&gt;%
    as.data.frame() %&gt;%
    as.matrix()
  </code></pre>
  
  <p>Step 4: Based on m_NA to replace those TRUE with NA in alldata_int, and then the work is done:</p>
  
  <pre><code>alldata_int[m_NA] &lt;- NA
  </code></pre>
  
  <p>When I run Step 4, I get this error:</p>
  
  <pre><code>Error in `[&lt;-.data.frame`(`*tmp*`, m_NA, value = NA) : unsupported matrix index in replacement
  </code></pre>
  
  <p>I think this is because of the additional non-numeric columns to the left of the timestamp column. Is there a simple way to adjust this code to deal with this? Or a better solution?</p>