In many programming languages there is a mechanism to get a list of the formal parameter names and their associated values of the calling function from within the function -- typically as an array or a named list. For instance, if I ran:
I'd like the error message to say '"Happy Birthday" is not numeric.', rather than "multiplicand is not numeric."
I'd like to be able to consult an object within the called function's scope that gives not just the formal parameter name of the value that causes the error, but the name of the erroneous object in the called function's parent scope. Is there a mechanism to accomplish this within R? Thanks in advance to anyone that can tell me how to do this.
Larry Hunsicker
Thanks, williaml. Your solution works for the problem that I set, but not for what I was looking for. After noodling around some more, I found the solution in IRTFM's reply/solution in:
Use deparse(subsitiute() as in the code below:
# Create a (nonsense) data.frame and survfit object:
library(survival)
library(glue)
library(magrittr)
library(dplyr)
data1 <- data.frame(status = sample(0:1, 50, replace = T), sex = sample(0:1, 50, replace = T))
data1 %<>% mutate(time1 = ifelse(status == 1, rnorm(50, 5,2), .2*rnorm(50,5,2)),
time1 = ifelse(sex == 1, time1 + 5, time1))
data1$time1 <- with(data1, ifelse(time1 <=0, 0.1, time1))
data1$time <- with(data1, ifelse(sex == 1, time1 + 2, time1))
fit1 <- survfit(Surv(time1, status) ~ sex, data = data1)
# create a function to test whether there is a mismatch in length between the model and the parameter levels.
matchlength <- function(sfit, strata) {
modnm <- deparse(substitute(sfit))
if (length(unique(summary(sfit)$strata)) == length(strata))
return(strata)
else
stop(glue("{modnm} has {length(sfit$strata)} strata; length(strata) is {length(strata)}."), call. = F)
}
# Test the models with a correct length match and one with a length mismatch.
matchlength(fit1, strata = c("IAK", "IA"))
# [1] "IAK" "IA"
matchlength(fit1, strata = c("IAK", "IA", "IAB"))
# Error: fit1 has 2 strata; length(strata) is 3.
As I understand it, the function call passes the body of the parameter to the function's scope. But a reference to the passed parameter returns the print version of the call not the name of the object in the parent environment. Generally, the print value of a call is the same as the name of the object in the parent scope. But the print() version of lots of functions is the result of the function, not the name of the function in the parent environment. The example here is that if "a" is a survfit object, print(a) gives a formatted output of the function. To get the name of the object in the parent scope, one uses deparse(substitute(a)).