title: Using dplyr summarise_if() with a predicate
body: <p>I want to calculate mean of x1 and x2 <strong>on days where the ratio of sum(is.NA) and all observations is >= 0.5</strong> or else NA.</p>
  
  <p>Data:</p>
  
  <pre class="lang-r prettyprint-override"><code>library(lubridate)
  library(dplyr)
  
  x = seq(length.out= 10)
  x[seq(1,11,5)] &lt;- NA
  data = data.frame(
      tseq = seq(from = Sys.time(), length.out = 11, by = "12 hours"),
      x1 = x,
      x2 = x
      )
  
  means = data %&gt;% group_by(tseq=floor_date(tseq, "days")) %&gt;%
      summarise_all(list( mean = ~ mean(., na.rm = TRUE)))
  
  ratio = data %&gt;% group_by(tseq=floor_date(tseq, "days")) %&gt;%
      summarise_all(list( ratio = ~ sum(is.na(.)) / n()))
  </code></pre>
  
  <pre class="lang-r prettyprint-override"><code>&gt; ratio
    tseq                x1_ratio x2_ratio
  1 2019-08-26 00:00:00      1        1  
  2 2019-08-27 00:00:00      0        0  
  3 2019-08-28 00:00:00      0        0  
  4 2019-08-29 00:00:00      0.5      0.5
  5 2019-08-30 00:00:00      0        0  
  6 2019-08-31 00:00:00      0.5      0.5
  </code></pre>
  
  <p>So here <em>2019-08-26, 2019-08-29, 2019-08-31</em> dates would get means.
  In a vector I could accomplish this by function</p>
  
  <pre class="lang-r prettyprint-override"><code>isEnough = function(x){
      # is there enough values to calculate mean
      if (sum(is.na(x)) / length(x) &lt; 0.5){
          return(FALSE)
      }
      else return(TRUE)
  }
  </code></pre>
  
  <p>For a data frame I can't find a solution. So far I have tried</p>
  
  <pre class="lang-r prettyprint-override"><code>data %&gt;% group_by(tseq=floor_date(tseq, "days")) %&gt;%
      summarise_if(.predicate =  isEnough(~ sum(is.na(.)), ~n()),
      .funs = list( mean = ~ mean(., na.rm = TRUE)))
  Error in naCount/xLength : non-numeric argument to binary operator
  
  data %&gt;% group_by(tseq=floor_date(tseq, "days")) %&gt;%
      summarise_if(.predicate = list( ~ sum(is.na(.)) / n() &gt; 0.5),
      .func = list( mean = ~ mean(., na.rm = TRUE)))
  Error: n() should only be called in a data context
  
  data %&gt;% group_by(tseq=floor_date(tseq, "days")) %&gt;%
      summarise_if(.predicate = (~ sum(is.na(.)) / ~n() &gt; 0.5),
      .func = list( mean = ~ mean(., na.rm = TRUE)))
  Error in sum(is.na(.))/~n() &gt; 0.5 : 
    non-numeric argument to binary operator
  </code></pre>