Problems with using identical() in dplyr::mutate()
<p>I'd like to use <code>identical()</code> inside <code>mutate()</code> and I'm getting "strange" results. Am I missing something here or is this a bug?</p>

<p>Consider the following example:</p>

<pre><code>dat &lt;- data.frame(x = 1:4, y = c(1, 2, 10, NA))
</code></pre>

<p>I'd like to check if <code>y</code> differs from <code>x</code>:</p>

<pre><code>mutate(dat, diff = x != y)
# x  y  diff
# 1 1  1 FALSE
# 2 2  2 FALSE
# 3 3 10  TRUE
# 4 4 NA    NA
</code></pre>

<p>Has "problems" with NA, so I turned to identical:</p>

<pre><code>mutate(dat, diff = !identical(x, y))
# x  y diff
# 1 1  1 TRUE
# 2 2  2 TRUE
# 3 3 10 TRUE
# 4 4 NA TRUE
</code></pre>

<p>Hm, that's kinda strange >> investigated and found out it had to do with diverging data types:</p>

<pre><code>class(dat$x)
# [1] "integer"
class(dat$y)
# [1] "numeric"
</code></pre>

<p>So let's take care of aligning that:</p>

<pre><code>dat$x &lt;- as.numeric(dat$x)
dat$y &lt;- as.numeric(dat$y)
</code></pre>

<p>Now, I would intuitively think that mutate would give me the same result as this:</p>

<pre><code>sapply(1:nrow(dat), function(ii) {
  !identical(dat[ii, "x"], dat[ii, "y"])
})
# [1]  FALSE FALSE TRUE TRUE
</code></pre>

<p>But it still gives me this:</p>

<pre><code>mutate(dat, diff = !identical(x, y))
# x  y diff
# 1 1  1 TRUE
# 2 2  2 TRUE
# 3 3 10 TRUE
# 4 4 NA TRUE
</code></pre>

<p>while I'd expect this</p>

<pre><code># x  y diff
# 1 1  1 FALSE
# 2 2  2 FALSE
# 3 3 10 TRUE
# 4 4 NA TRUE
</code></pre>

<p>What's the reason for this and/or how would I work around this so I could still use <code>mutate</code> (which I really like)?</p>

<hr>

<h2>Update</h2>

<p>Wow, what a difference in speed!</p>

<pre><code>identicalVectorized &lt;- function(x, y) {
  (x != y | (is.na(x) | is.na(y))) &amp; !(is.na(x) &amp; is.na(y))
}

identicalVectorized2 &lt;- function(x, y) {
  sapply(1:length(x), function(ii) {
    !identical(x[ii], y[ii])
  })
}

dat &lt;- data.frame(x = as.numeric(c(1:4,NA, NA)), 
    y = as.numeric(c(1, 2, 10, NA, 15, NA)))

microbenchmark::microbenchmark(
  mutate(dat, diff = identicalVectorized(x, y)),
  mutate(dat, diff = identicalVectorized2(x, y))
)
</code></pre>

<p>Result</p>

<pre><code>Unit: microseconds
                                           expr    min     lq     mean median      uq     max neval
  mutate(dat, diff = identicalVectorized(x, y)) 31.672 34.164 38.79999 35.777 37.6825 120.526   100
 mutate(dat, diff = identicalVectorized2(x, y)) 58.064 60.703 66.66150 62.462 72.7260 117.593   100
</code></pre>