Jim G.
Jim G.

Reputation: 15363

Why doesn't all.equal work within dplyr's mutate function?

Consider the following code:

library(dplyr)       
patientID <- c(1, 2, 3, 4)
age <- c(25, 34, 28, 52)
diabetes <- c("Type1", "Type2", "Type1", "Type1")
status <- c("Poor", "Improved", "Excellent", "Poor")
patientdata <- data.frame(patientID, age, diabetes, status)
myf <- function(patientID, age, diabetes, status) { isTRUE(all.equal(age, 34))}
mutate(patientdata, isAge34 = myf(patientID, age, diabetes, status))

I wrote myf to return TRUE for the row where age == 34, but this doesn't work:

  patientID age diabetes    status isAge34
1         1  25    Type1      Poor   FALSE
2         2  34    Type2  Improved   FALSE
3         3  28    Type1 Excellent   FALSE
4         4  52    Type1      Poor   FALSE

Why didn't this work? Did I doing something wrong?


EDIT: This is a contrived, simplified example. In reality, I have much more complicated logic inside of my function.

My motivation for asking:

Reference 1, Reference 2:

For numerical and complex values, remember == and != do not allow for the finite representation of fractions, nor for rounding error. Using all.equal with identical is almost always preferable. See the examples.

Upvotes: 3

Views: 678

Answers (2)

mikeck
mikeck

Reputation: 3776

The point of all.equal is to check for near equality, most commonly for use with floating point numbers. Comparisons with == will not give reliable results for floating point numbers (the link provided by @Andew's comment explains this). Therefore the accepted answer is not actually a correct solution, because the dataframe described in the original post specifies the age variable as numeric (not integer!).

dplyr provides the near function, which is basically a vectorized version of all.equal that works with mutate.

mutate(patientdata, isAge34 = near(age, 34))

Upvotes: 6

Jim G.
Jim G.

Reputation: 15363

As @DavidArenburg said, all.equal() is not vectorized.

The following code will work:

mutate(patientdata, isAge34 = age == 34)

Upvotes: 2

Related Questions