# Make R report error on using non-existent column name in a data frame

In our usage of R for a non-trivial data analysis and estimation project, we've been repeatedly burnt by how tolerant R is toward misspelled or missing columns in a data frame. Typical example is calculating the weighted mean of a variable MYVAR in a data frame using another variable WEIGHT for weights:

m <- weighted.mean(tbl$MYVAR, w = tbl$WEIGHT, na.rm = TRUE)


Suppose I make a typo in the WEIGHT name in the operation above. What will happen in that R will expand my misspelled column into NULL and will use it for performing the weighted mean resulting in a non-weighted one.

Therefore, the question: is there any way to make R treat attempts to "read" a non-existent variables in a data frame as an error?

Hmm... when I tried out your example with some fake data, weighted.mean() actually failed:

#Some fake data
dat <- data.frame(x = rnorm(100), weight = rnorm(100))

#The right weight var
weighted.mean(x = dat$x, w = dat$weight)
[1] 0.6161606

#Misspelled weight var
weighted.mean(x = dat$x, w = dat$wieght)
Error in weighted.mean.default(x = dat$x, w = dat$wieght) :
'x' and 'w' must have the same length


But anyway, another way to cope with this problem is to access your variables via indexing - it returns an error if you try to pick non-existant columns:

dat$wieght NULL dat[ , "wieght"] Error in [.data.frame(dat, , "wieght") : undefined columns selected weighted.mean(x = dat[ , "x"], w = dat[ , "wieght"], na.rm = TRUE) Error in [.data.frame(dat, , "wieght") : undefined columns selected  • Yes, this would definitely work but you have to admit that the syntax is somewhat unwieldy. dat[ , "WEIGHT"] is a lot less elegant compared to dat$WEIGHT. I just wondered why there is no option to turn on the behavior above? This sounds like a very reasonable feature. – Alexander L. Belikoff Nov 10 '10 at 22:14
• Also, on the heels of my last comment. I wonder if using attaching the data frame and then referencing the variables directly would mitigate this problem... – Alexander L. Belikoff Nov 10 '10 at 22:17
• I would definitely avoid using attach in all circumstances, but I think that's the right idea. You can use with() to attach a data frame for a single command: with(dat, weighted.mean(x, weight, na.rm = TRUE)). Also, many functions like weighted.mean include a data= option that essentially internalizes this. – Matt Parker Nov 10 '10 at 22:39

Maybe, you can enclose your code into try-catch blocks, see ?try and the associated examples. It is easy to test for the class of the results ("try-error") in turn, e.g.

> res <- try(log("A"), silent=TRUE)
> class(res)
[1] "try-error"


You can also test directly for the correct spelling, by first listing the variables of interest--in your case, MYVAR and WEIGHT-- and test that they are part of the data.frame df, e.g.

df <- data.frame(x=rnorm(100), g1=gl(2, 50), g2=gl(5,20))
sel.vars <- c("x","g2")
ifelse(all(sel.vars %in% colnames(df)), <compute things here>, "fail")

• Unfortunately, the snippet above would not help. Making sure that all columns (variables) are present in the data frame is one thing and it would never help against accidental misspelling of a variable name in some other corner of the code. – Alexander L. Belikoff Nov 10 '10 at 22:20