Skip to contents

switch() statements in R are used to delegate behavior based on the value of some input scalar string, e.g. switch(x, a = 1, b = 3, c = 7, d = 8) will be one of 1, 3, 7, or 8, depending on the value of x.

Usage

if_switch_linter(max_branch_lines = 0L, max_branch_expressions = 0L)

Arguments

max_branch_lines, max_branch_expressions

Integer, default 0 indicates "no maximum". If set any if/else if/.../else chain where any branch occupies more than this number of lines (resp. expressions) will not be linted. The conjugate applies to switch() statements -- if these parameters are set, any switch() statement with any overly-complicated branches will be linted. See examples.

Details

This can also be accomplished by repeated if/else statements like so: if (x == "a") 1 else if (x == "b") 2 else if (x == "c") 7 else 8 (implicitly, the last else assumes x only takes 4 possible values), but this is more cluttered and slower (note that switch() takes the same time to evaluate regardless of the value of x, and is faster even when x takes the first value (here a), and that the if/else approach is roughly linear in the number of conditions that need to be evaluated, here up to 3 times).

See also

linters for a complete list of linters available in lintr.

Examples

# will produce lints
lint(
  text = "if (x == 'a') 1 else if (x == 'b') 2 else 3",
  linters = if_switch_linter()
)

code <- paste(
  "if (x == 'a') {",
  "  1",
  "} else if (x == 'b') {",
  "  2",
  "} else if (x == 'c') {",
  "  y <- x",
  "  z <- sqrt(match(y, letters))",
  "  z",
  "}",
  sep = "\n"
)
writeLines(code)
#> if (x == 'a') {
#>   1
#> } else if (x == 'b') {
#>   2
#> } else if (x == 'c') {
#>   y <- x
#>   z <- sqrt(match(y, letters))
#>   z
#> }
lint(
  text = code,
  linters = if_switch_linter()
)
#> ::warning file=<text>,line=1,col=1::file=<text>,line=1,col=1,[if_switch_linter] Prefer switch() statements over repeated if/else equality tests, e.g., switch(x, a = 1, b = 2) over if (x == "a") 1 else if (x == "b") 2.

code <- paste(
  "if (x == 'a') {",
  "  1",
  "} else if (x == 'b') {",
  "  2",
  "} else if (x == 'c') {",
  "  y <- x",
  "  z <- sqrt(",
  "    match(y, letters)",
  "  )",
  "  z",
  "}",
  sep = "\n"
)
writeLines(code)
#> if (x == 'a') {
#>   1
#> } else if (x == 'b') {
#>   2
#> } else if (x == 'c') {
#>   y <- x
#>   z <- sqrt(
#>     match(y, letters)
#>   )
#>   z
#> }
lint(
  text = code,
  linters = if_switch_linter()
)
#> ::warning file=<text>,line=1,col=1::file=<text>,line=1,col=1,[if_switch_linter] Prefer switch() statements over repeated if/else equality tests, e.g., switch(x, a = 1, b = 2) over if (x == "a") 1 else if (x == "b") 2.

code <- paste(
  "switch(x,",
  "  a = {",
  "    1",
  "    2",
  "    3",
  "  },",
  "  b = {",
  "    1",
  "    2",
  "  }",
  ")",
  sep = "\n"
)
writeLines(code)
#> switch(x,
#>   a = {
#>     1
#>     2
#>     3
#>   },
#>   b = {
#>     1
#>     2
#>   }
#> )
lint(
  text = code,
  linters = if_switch_linter(max_branch_lines = 2L)
)
#> ::warning file=<text>,line=1,col=1::file=<text>,line=1,col=1,[if_switch_linter] Prefer repeated if/else statements over overly-complicated switch() statements.

# okay
lint(
  text = "switch(x, a = 1, b = 2, 3)",
  linters = if_switch_linter()
)

# switch() version not as clear
lint(
  text = "if (x == 'a') 1 else if (x == 'b' & y == 2) 2 else 3",
  linters = if_switch_linter()
)

code <- paste(
  "if (x == 'a') {",
  "  1",
  "} else if (x == 'b') {",
  "  2",
  "} else if (x == 'c') {",
  "  y <- x",
  "  z <- sqrt(match(y, letters))",
  "  z",
  "}",
  sep = "\n"
)
writeLines(code)
#> if (x == 'a') {
#>   1
#> } else if (x == 'b') {
#>   2
#> } else if (x == 'c') {
#>   y <- x
#>   z <- sqrt(match(y, letters))
#>   z
#> }
lint(
  text = code,
  linters = if_switch_linter(max_branch_lines = 2L)
)

code <- paste(
  "if (x == 'a') {",
  "  1",
  "} else if (x == 'b') {",
  "  2",
  "} else if (x == 'c') {",
  "  y <- x",
  "  z <- sqrt(",
  "    match(y, letters)",
  "  )",
  "  z",
  "}",
  sep = "\n"
)
writeLines(code)
#> if (x == 'a') {
#>   1
#> } else if (x == 'b') {
#>   2
#> } else if (x == 'c') {
#>   y <- x
#>   z <- sqrt(
#>     match(y, letters)
#>   )
#>   z
#> }
lint(
  text = code,
  linters = if_switch_linter(max_branch_expressions = 2L)
)

code <- paste(
  "switch(x,",
  "  a = {",
  "    1",
  "    2",
  "    3",
  "  },",
  "  b = {",
  "    1",
  "    2",
  "  }",
  ")",
  sep = "\n"
)
writeLines(code)
#> switch(x,
#>   a = {
#>     1
#>     2
#>     3
#>   },
#>   b = {
#>     1
#>     2
#>   }
#> )
lint(
  text = code,
  linters = if_switch_linter(max_branch_lines = 3L)
)