Christoph
Christoph

Reputation: 7063

Is there a build-in function in R to check whether the variable type is preserved?

Assume you have an input a which goes into an existing function fun. I am looking for a function preserved(a, fun(a)), which returns TRUE, if the type is unchanged, FALSE otherwise.

Example:

a <- 1L # [1] 1 - integer
b <- a[FALSE] # integer(0)
c <- a[2] # [1] NA
d <- ncol(a) # NULL
e <- a/0 # [1] Inf
f <- 1 # [1] 1 - numeric
g <- as.factor(a) # [1] 1 Levels: 1

Expected output:

preserved(a, 2L) = TRUE
preserved(a, b) = FALSE
preserved(a, c) = FALSE
preserved(a, d) = FALSE
preserved(a, e) = FALSE
preserved(a, f) = FALSE
preserved(a, f) = FALSE
preserved(a, g) = FALSE

A bad hack (not vectorized) would be

preserved <- function(a, b) {
  if (length(b) == length(a)) {
    if (is.na(b) == is.na(a) & 
        class(b) == class(a) &
        is.null(b) == is.null(a) &
        is.nan(b) == is.nan(a) &
        is.factor(b) == is.factor(a)) {
      return(TRUE)
    } else {
      return(FALSE)
    }
  } else {
    return(FALSE)
  }
}

Upvotes: 3

Views: 76

Answers (1)

Thomas
Thomas

Reputation: 44585

If you just want to compare two objects, you probably want to use all.equal() or identical() rather than trying to generate every possible pairwise combination of classes (since that number could be infinite).

Something close to what you want that might be more useful is applying makeActiveBinding() to issue messages (or warnings or errors) if type coercion is attempted:

# active binding
preserved <- local( {
    x <- NULL
    function(v) {
        if (!missing(v)) {
            if (class(x) != class(v)) {
                message(sprintf("Object is being coerced from %s to %s", class(x), class(v)))
            }
            x <<- v
        }
        x
    }
})
makeActiveBinding("z", preserved, .GlobalEnv)
z
## NULL
z <- 2
## Object is being coerced from NULL to numeric
z <- "hello"
## Object is being coerced from numeric to character
z <- factor("a", levels = c("a", "b", "c"))
## Object is being coerced from character to factor
z
## [1] a
## Levels: a b c

Upvotes: 2

Related Questions