Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable declaration / "option explicit" in R

Tags:

r

R is fantastic: lean and flexible, but powerful and open. For small tasks it is convenient if one does not have to declare each variable before use. BUT: esp. in larger projects, small typos can mess up everything, possibly even without an eror message (see example)!

Is there a workaround? If not within plain R, possibly also by an editor that asks for a declaration block? Something like "option explicit" in VBA? I am aware of the very nice highlighting of same variables in the RStudio editor when marking it, but if variables in question are far apart this becomes less useful.

Just for clarity: I am not looking for a more elegant/less error-prone implementation of this function, which was created merely to provide a demo.

# without typo
fun <- function(x) {
  a <- x
  if (a<0) {
    if (a > -50) x <- -1 else x <- -2
  }
  return(x)
}

# even if masters will spot the typo on the first glance...
fun.typo <- function(x) {
  a <- x
  if (a<0) {
    if (a > -50) x <- -1 else X <- -2
  }
  return(x)
}

fun( 50) # 50
fun(-40) # -1
fun(-60) # -2

fun.typo( 50) #  50
fun.typo(-40) #  -1
fun.typo(-60) # -60 (*** unintended, should be -2 ***)
like image 825
Martin Avatar asked Dec 19 '25 01:12

Martin


1 Answers

A very "dirty" solution would be to systematically check that the function's local environment is not changed after the "preamble".

fun <- function(x) {
  a <- x
  ls1 <- ls()
  if (a<0) {
    if (a > -50) x <- -1 else x <- -2
  }
  ls2 <- ls()
  print(list(c(ls1,"ls1"),ls2))
  if (!setequal(c(ls1,"ls1"), ls2)) stop("Something went terribly wrong!")
  return(x)
}

fun.typo <- function(x) {
  a <- x
  ls1 <- ls()
  if (a<0) {
    if (a > -50) x <- -1 else X <- -2
  }
  ls2 <- ls()
  print(list(c(ls1,"ls1"),ls2))
  if (!setequal(c(ls1,"ls1"), ls2)) stop("Something went terribly wrong!")
  return(x)
}

With this "solution", fun.typo(-60) no longer silently gives a wrong answer...

like image 157
Vincent Guillemot Avatar answered Dec 20 '25 15:12

Vincent Guillemot