Formatting Options

Formatting Options

rformat applies base R style conventions to R code. All transforms operate on the token stream from parse() + getParseData(), so they never change the meaning of your code – only its whitespace and style.

This vignette walks through each option with before/after examples.

Default formatting

With no options, rformat normalizes spacing, converts = assignment to <-, and indents by nesting depth.

> library(rformat)
> cat(rformat("x=1+2"))
x <- 1 + 2
> cat(rformat("f=function(x,y){
+ if(x>0)
+ y=mean(x,na.rm=TRUE)
+ else y=NA
+ }"))
f <- function(x, y) {
    if (x > 0)
    y <- mean(x, na.rm = TRUE)
    else y <- NA
}

indent

Indentation per nesting level. Default is 4 spaces. Pass an integer for spaces or a character string for a literal indent.

> # 2 spaces per level
> cat(rformat("f <- function(x) {\nif (x) {\ny\n}\n}", indent = 2L))
f <- function(x) {
  if (x) {
    y
  }
}
> # Tab indent (shown as \t in output)
> rformat("f <- function(x) {\nif (x) {\ny\n}\n}", indent = "\t")
[1] "f <- function(x) {\n\tif (x) {\n\t\ty\n\t}\n}\n"

line_limit

Maximum line width before wrapping kicks in (default 80). This affects function signature wrapping and long expression wrapping.

> long_call <- "result <- some_function(alpha, bravo, charlie, delta)"
> # Default 80: fits on one line
> cat(rformat(long_call))
result <- some_function(alpha, bravo, charlie, delta)
> # Narrow limit: forces wrapping
> cat(rformat(long_call, line_limit = 40))
result <- some_function(alpha, bravo,
    charlie, delta)

wrap

Controls continuation indent style for wrapped function signatures.

> long_sig <- paste0(
+     "my_function <- function(alpha, beta, gamma, ",
+     "delta, epsilon, zeta, eta, theta, iota) ",
+     "{\n    1\n}")
> # Paren-aligned (default): continuation aligns to (
> cat(rformat(long_sig, wrap = "paren"))
my_function <- function(alpha, beta, gamma, delta, epsilon, zeta, eta, theta,
                        iota) {
    1
}
> # Fixed: continuation uses 8-space indent
> cat(rformat(long_sig, wrap = "fixed"))
my_function <- function(alpha, beta, gamma, delta, epsilon, zeta, eta, theta,
        iota) {
    1
}

brace_style

Controls opening brace placement for function definitions.

> long_def <- paste0(
+     "my_function <- function(alpha, beta, gamma, ",
+     "delta, epsilon, zeta, eta, theta, iota) ",
+     "{\n    y <- 1\n    y\n}")
> # K&R (default): { on same line as )
> cat(rformat(long_def, brace_style = "kr"))
my_function <- function(alpha, beta, gamma, delta, epsilon, zeta, eta, theta,
                        iota) {
    y <- 1
    y
}
> # Allman: { on its own line
> cat(rformat(long_def, brace_style = "allman"))
my_function <- function(alpha, beta, gamma, delta, epsilon, zeta, eta, theta,
                        iota)
{
    y <- 1
    y
}

control_braces

When TRUE, adds braces to bare (unbraced) control flow bodies. Default FALSE matches R Core source code, where 59% of control flow bodies are bare.

> code <- "f <- function(x) {
+ if (x > 0) y <- log(x)
+ if (x < 0) stop('negative')
+ }"
> # Default: bare bodies left alone
> cat(rformat(code))
f <- function(x) {
    if (x > 0) y <- log(x)
    if (x < 0) stop('negative')
}
> # Add braces
> cat(rformat(code, control_braces = TRUE))
f <- function(x) {
    if (x > 0) { y <- log(x) }
    if (x < 0) { stop('negative') }
}

expand_if

When TRUE, expands inline if-else expressions to multi-line form.

> code <- "y <- if (x > 0) log(x) else NA"
> # Default: inline if-else preserved
> cat(rformat(code))
y <- if (x > 0) log(x) else NA
> # Expanded to multi-line
> cat(rformat(code, expand_if = TRUE))
if (x > 0) {
    y <- log(x)
} else {
    y <- NA
}

else_same_line

In R, else on its own line is a parse error at top level (though it’s valid inside braces). When TRUE (default), this option repairs top-level }\nelse by joining them to } else before formatting. When FALSE, unparseable input is returned unchanged with a warning.

> # Top-level } else on separate lines is a parse error.
> # else_same_line (the default) repairs it:
> code <- "if (x) {\n    1\n}\nelse {\n    2\n}"
> cat(rformat(code))
if (x) {
    1
} else {
    2
}

join_else

When TRUE (default), moves else to the same line as the preceding }. Matches R Core source code where 70% use same-line else. When FALSE, }\nelse on separate lines is preserved.

This is an AST-level transform that works on already-valid code inside braces, unlike else_same_line which is a text-level parse repair.

> code <- "f <- function(x) {
+ if (x > 0) {
+     y <- log(x)
+ }
+ else {
+     y <- NA
+ }
+ y
+ }"
> # Default: else joins the } line
> cat(rformat(code))
f <- function(x) {
    if (x > 0) {
        y <- log(x)
    } else {
        y <- NA
    }
    y
}
> # Preserve } / else on separate lines
> cat(rformat(code, join_else = FALSE))
f <- function(x) {
    if (x > 0) {
        y <- log(x)
    }
    else {
        y <- NA
    }
    y
}

function_space

When TRUE, adds a space before ( in function definitions: function (x) instead of function(x). Default FALSE matches 96% of R Core source code.

> code <- "f <- function(x, y) {\n    x + y\n}"
> # Default: no space
> cat(rformat(code))
f <- function(x, y) {
    x + y
}
> # With space
> cat(rformat(code, function_space = TRUE))
f <- function (x, y) {
    x + y
}

Combining options

Options compose naturally. Here is a more opinionated style that adds braces, expands if-else, and uses Allman braces with 2-space indent:

> code <- "f=function(x){
+ y=if(x>0) log(x) else NA
+ y
+ }"
> cat(rformat(code,
+     indent = 2L,
+     brace_style = "allman",
+     control_braces = TRUE,
+     expand_if = TRUE))
f <- function(x) {
  if (x > 0) {
    y <- log(x)
  } else {
    y <- NA
  }
  y
}

Formatting files and directories

rformat_file() formats a file in place (or to a new path). rformat_dir() formats all .R files in a directory. Both accept the same options as rformat().

> # Format a file (dry run)
> f <- tempfile(fileext = ".R")
> writeLines("x=1+2", f)
> rformat_file(f, dry_run = TRUE)
> # Format all R files in a directory (dry run)
> d <- file.path(tempdir(), "rformat_demo")
> dir.create(d, showWarnings = FALSE)
> writeLines("y = 3", file.path(d, "example.R"))
> rformat_dir(d, dry_run = TRUE)
Would format: /tmp/RtmpqnaPGt/rformat_demo/example.R
 
> unlink(d, recursive = TRUE)
> unlink(f)

mirror server hosted at Truenetwork, Russian Federation.