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)
}
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With