Getting Help and Documentation

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

Checked against R 4.6.1 (2026-06-24) on 2026-10-20; R 4.6.2 is scheduled for 2026-10-29. Every example on this page was run with Rscript on R 4.6.1 in a container; the printed results are shown as #> comments, trimmed where the text says so, and with platform strings (operating system, library paths, BLAS) removed. Two packages outside base R appear: dplyr 1.2.1, only to list its vignettes, and readr 2.2.0, only to show try.all.packages. The reprex package, the ctv package and the interactive helpers (help.start(), browseVignettes(), RSiteSearch(), bug.report()) are not run here: they open a browser or need a network or a clipboard, so they are labelled as fragments and described from their documentation.

R documents itself in three layers. The first is inside R: the Rd help pages of every function, data set and package, the vignettes and demos that packages ship, and the functions that search all of that. The second is the official manuals and the R FAQ, which describe the language and the system as a whole. The third is the community around the project: the mailing lists, the bug tracker, the Task Views and the blogs. This page walks from the first layer to the third, and ends with the two things that make help possible in both directions: a reproducible example, and the real text of the messages R prints when a help function cannot find what you asked for. The examples use the small books.csv file of the running Shelf scenario, so the help page used throughout is the one for read.csv, the function that reads it; the file itself is read on Reading and Writing Text Data, and the data frame it produces is described on Data Frames.

Where to look first

Most questions fall into one of a few shapes, and each shape has a function that answers it. The rest of the page explains each row.

The question The tool Section

What does this function do, and what are its arguments?

?read.csv, help("read.csv")

Reading a help page

I do not know the name of the function.

??"read csv", help.search(), apropos("read")

Searching the help system

Which package does this name come from, and what is its source?

find(), getAnywhere(), getS3method(), printing the name

Inspecting objects

Show me how it is used.

example(), demo(), vignette(), browseVignettes()

Examples, demos and vignettes

How does the language itself work?

RShowDoc("R-lang") and the other manuals, the R FAQ

The manuals and the R FAQ

What changed between versions? How do I cite R?

news(), RShowDoc("NEWS"), citation()

News, citation and version

Where are the packages for my topic?

CRAN Task Views, search.r-project.org

Community resources

Something is wrong and I need to ask.

sessionInfo(), dput(), help.request(), bug.report()

Asking well: reproducible examples and bug reports

Reading a help page

A help page is the rendering of an Rd file, the documentation format of R (written by package authors with the tools described on Documentation with Rd, roxygen2 and Vignettes). Every page has the same skeleton, which is why a reader who has learned it once can read any page of any package: a title, then Description, Usage, Arguments, Details, Value, optional sections such as Note or Warning, References, See Also and Examples. The format and its sections are defined in Writing R Extensions: Rd format.

The first line of a text page has three parts: the name of the Rd file, the package it belongs to, and the words R Documentation. The file name is not always the name of the function. One page documents a family of related functions, so read.csv, read.csv2, read.delim, read.delim2 and read.table all open the page read.table of the utils package. The next block makes this visible. Text help is sent to the pager, a program that shows a file; options(pager =) accepts an R function instead, so the script below prints the page to the console, which lets it be captured and trimmed. The pager function also removes the overstrike marks (_ followed by a backspace) that text help uses to underline headings.

# Text help goes to the pager. A pager can be a function, so print the file
# (removing the overstrike marks that underline the headings) and capture it.
options(pager = \(files, ...) {
  writeLines(gsub("_\b", "", readLines(files), fixed = TRUE))
})
help_lines <- \(topic) capture.output(help(topic))
page <- help_lines("read.csv")

# The first line names the Rd file (read.table), the package and the format.
page[1]
#> [1] "read.table                package:utils                R Documentation"
# The second paragraph is the title; headings end with a colon.
page[3]
#> [1] "Data Input"
grep("^[[:alpha:]][[:alpha:] ]*:$", page, value = TRUE)
#>  [1] "Description:"  "Usage:"        "Arguments:"    "Details:"
#>  [5] "Value:"        "CSV files:"    "Memory usage:" "Note:"
#>  [9] "References:"   "See Also:"     "Examples:"

# Usage: one page documents five functions; these are two of the entries.
usage <- page[(grep("^Usage:", page) + 1L):(grep("^Arguments:", page) - 1L)]
cat(usage[2L:3L], sep = "\n")
#>      read.table(file, header = FALSE, sep = "", quote = "\"'",
#>                 dec = ".", numerals = c("allow.loss", "warn.loss", "no.loss"),
first <- grep("^ +read\\.csv\\(", usage)
cat(usage[first:(first + 1L)], sep = "\n")
#>      read.csv(file, header = TRUE, sep = ",", quote = "\"",
#>               dec = ".", fill = TRUE, comment.char = "", ...)

# A generic with methods lists them with the class they are for.
summary_page <- help_lines("summary")
at <- grep("S3 method for class 'data.frame'", summary_page)
cat(summary_page[at:(at + 2L)], sep = "\n")
#>      ## S3 method for class 'data.frame'
#>      summary(object, maxsum = 7,
#>              digits = max(3, getOption("digits")-3), ...)

# Arguments: each entry starts with the argument name and a colon.
at <- grep("^ +header:", page)
cat(page[at:(at + 4L)], sep = "\n")
#>   header: a logical value indicating whether the file contains the
#>           names of the variables as its first line.  If missing, the
#>           value is determined from the file format: ‘header’ is set to
#>           ‘TRUE’ if and only if the first row contains one fewer field
#>           than the number of columns.

# Value and Examples are the sections to read last, and run first.
at <- grep("^Value:", page)
cat(page[(at + 2L):(at + 3L)], sep = "\n")
#>      A data frame (‘data.frame’) containing a representation of the
#>      data in the file.

The same page, as R shows it on a Unix-alike, abridged to the parts that matter for a first read. The quoted lines are verbatim; [...] marks text left out.

read.table                package:utils                R Documentation

Data Input

Description:

     Reads a file in table format and creates a data frame from it,
     with cases corresponding to lines and variables to fields in the
     file.

Usage:

     read.table(file, header = FALSE, sep = "", quote = "\"'",
                [...]
     read.csv(file, header = TRUE, sep = ",", quote = "\"",
              dec = ".", fill = TRUE, comment.char = "", ...)
     [...]
Arguments:

    file: the name of the file which the data are to be read from.
          Each row of the table appears as one line of the file.  If it
          does not contain an _absolute_ path, the file name is
          _relative_ to the current working directory, ‘getwd()’.
  [...]
  header: a logical value indicating whether the file contains the
          names of the variables as its first line.  If missing, the
          value is determined from the file format: ‘header’ is set to
          ‘TRUE’ if and only if the first row contains one fewer field
          than the number of columns.
  [...]
     ...: Further arguments to be passed to ‘read.table’.

Value:

     A data frame (‘data.frame’) containing a representation of the
     data in the file.

How to read it, section by section:

Section What to look for

Title and Description

One sentence on what the function is for. If the title is not what you expected, stop: you opened the wrong page.

Usage

The calling form, with every argument and its default. header = TRUE for read.csv against header = FALSE for read.table is the whole difference between the two, and the Details section says so. An argument without a default (file) must be supplied. The ... argument means "further arguments"; its entry in Arguments says where they go (here, to read.table). When a generic has methods, each is listed under a comment such as ## S3 method for class 'data.frame', which names the class the method is for (see the summary example above and S3 Classes and Generics).

Arguments

One entry per argument, in the order of the Usage. Each entry gives the type that is expected and what the argument does. Arguments listed together (x, y:) share one description.

Details

The rules that do not fit a one-line entry: how a default is decided, which arguments interact, and the edge cases. This is where "if missing, the value is determined from the file format" is explained.

Value

What comes back, including its class. For read.csv it is a data frame; the page also says when the columns are logical and when the result has zero rows.

Note, Warning, References

Platform differences, known traps and the literature behind an algorithm.

See Also

The neighbouring functions. Follow these links before searching again: they are the author’s own answer to "what else is there?".

Examples

Code that runs. Copy it, change one thing, run it again. example() runs the section for you (see Examples, demos and vignettes).

Two details of the rendering are worth knowing. Text help uses directional quotes in a UTF-8 locale; options(useFancyQuotes = FALSE) turns them back into plain quotes where a terminal font cannot draw them. And the help page is the contract: when a function does something unexpected, the Details and Value sections say whether that was designed, and an argument list that disagrees with the page is a bug that R FAQ 9.1 asks to be reported.

Opening help with ? and help()

help() is the primary interface to the help system, and ? is its shortcut: ?topic is help("topic") with the same default type of help. The forms that exist, all documented on the ? page and on the help page, are these.

Form Meaning

?read.csv, help(read.csv), help("read.csv")

The help page that has the alias read.csv. Quotes are optional for a syntactically valid name.

?"if", help("if")

Reserved words and control-flow keywords (if, else, for, in, repeat, while, break, next and function) must be quoted because they cannot stand alone as an expression. TRUE, NA and Inf are reserved words too, but they can be written without quotes.

?`+`, ?"+"

Operators must be quoted, with either quotes or backticks. All the arithmetic operators (+, -, *, / and ^) open the page Arithmetic; ?"[[" opens Extract; ?"%in%" opens match.

?utils::read.csv, help("read.csv", package = "utils")

Look in one package only. pkg::topic and pkg:::topic are understood by ?. By default help() searches the packages whose namespaces are loaded (the package argument documents it), so a function in an installed but not loaded package needs this form.

package?stats, help("stats-package")

The overview page of a package, if the author wrote one. type?topic is the general form; class?name and methods?name do the same for S4 classes and the methods of a generic.

??"linear model", help.search("linear model")

Search by words instead of by name (next section).

help(package = "stats")

An index of the package: its DESCRIPTION fields, a one-line title for every help page and its vignettes. It works when the package is installed but not loaded.

The script below checks the claims made in this table against the installation. help() returns the path of the Rd file it found, whose base name is the name of the page (Arithmetic for +, Question for ? itself), so the same call is a way to learn which page documents a name.

# help() returns the path of the Rd file that documents a topic. Its base
# name is the page name, which is not always the name of the function.
topics <- c("read.csv", "if", "+", "[[", "%in%", "?", "??", "women")
pages <- vapply(topics, \(topic) basename(help(topic)), character(1L))
data.frame(topic = topics, page = unname(pages))
#>      topic        page
#> 1 read.csv  read.table
#> 2       if     Control
#> 3        +  Arithmetic
#> 4       [[     Extract
#> 5     %in%       match
#> 6        ?    Question
#> 7       ?? help.search
#> 8    women       women

# Overview pages of packages and S4 classes have their own topic names.
basename(help("stats-package"))
#> [1] "stats-package"
basename(help("data.frame-class"))
#> [1] "setOldClass"

# A variable holding a single string works as a topic (see the Arguments
# section of ?help); parentheses are the documented way to force it.
topic <- "mean"
basename(help((topic)))
#> [1] "mean"

# A topic that does not exist: the message is printed, not signalled.
capture.output(help("foo"))
#> [1] "No documentation for ‘foo’ in specified packages and libraries:"
#> [2] "you could try ‘??foo’"

# Restrict the search to one package, or look in every installed package.
basename(help("lm", package = "stats"))
#> [1] "lm"
x <- capture.output(help("read_csv", try.all.packages = TRUE))
sub("/.*$", "<library>", x[nzchar(x)])
#> [1] "Help for topic ‘read_csv’ is not in any loaded package but can be found"
#> [2] "in the following packages:"
#> [3] "  Package               Library"
#> [4] "  readr                 <library>"

# help(package =) describes a package: its DESCRIPTION fields, the index of
# its help pages and its vignettes, even when the package is not loaded.
info <- help(package = "stats")
class(info)
#> [1] "packageInfo"
info$info[[1L]][1:4]
#> [1] "Package:            stats"
#> [2] "Version:            4.6.1"
#> [3] "Priority:           base"
#> [4] "Title:              The R Stats Package"
grep("^lm  ", info$info[[2L]], value = TRUE)
#> [1] "lm                      Fitting Linear Models"
info$info[[3L]]
#>      [,1]      [,2]
#> [1,] "reshape" "Using the reshape function (source, pdf)"

# The kind of help is chosen by help_type; the option is unset here and the
# result of help() records the type it used (text under Rscript).
getOption("help_type")
#> NULL
attr(help("lm"), "type")
#> [1] "text"

The arguments of help(), in the order of its usage:

  • topic: a name or a character string. A string is always a topic. A name is taken literally unless it holds a length-one character vector, in which case the value is the topic (the help page recommends help((topic)) when a name must be evaluated). Omit it and help() gives help on help, or information on the package if package is given.

  • package and lib.loc: where to look. With package unset, the packages whose namespaces are loaded are searched first, then the libraries. The installed packages that are not loaded are the reason for the next argument.

  • try.all.packages: if the search fails, search every installed package and list those where the topic exists, as the read_csv call above did for readr. Its default is the option help.try.all.packages, which is FALSE. The search can be slow the first time.

  • help_type: "text", "html" or "pdf" (partial matching and any case). The default is getOption("help_type"); the help page documents text help on Unix-alikes, with the macOS GUI as the exception, and a choice made at installation time on Windows, where HTML is the factory-fresh default. PDF help is typeset with pdflatex, so it needs a working TeX installation. HTML help runs a small local web server and opens the page with browseURL(), which is why it cannot be shown in a batch run.

  • verbose: report the name of the file that was found.

When several pages match a topic, an interactive session offers a menu and a batch run takes the first one on the search path. In the interactive session the commands look like this; there is no output to quote, because the page opens in the pager, the browser or the IDE help pane.

?read.csv                              # text, HTML or IDE pane, depending on help_type
?"if"                                  # reserved words need quotes
?"[["                                  # so do operators; backticks work as well
?utils::read.csv                       # one package only
package?stats                          # the overview page of a package
help("read.csv", help_type = "html")   # force HTML help
help("lm", package = "stats")          # look in one package, loaded or not
help(package = "stats")                # index of a package

This block is a fragment for an interactive session: nothing in it is meant to be run by Rscript. The IDE help panes (see IDEs and the R Console) show the same Rd pages; what differs is how a page is displayed, not its content.

help.start() opens the HTML version of the help system in a browser: a start page with links to the locally installed manuals, the package index and the other documentation. It needs the small HTTP server that R starts for dynamic help (startDynamicHelp), so it is for interactive use. The page that it opens has a "Search Engine and Keywords" link, which R-intro recommends as a way to get one’s bearings (it is an interface to help.search(), R FAQ 7.24). update = TRUE refreshes the package index first, browser names the browser program (or an R function that is called with the URL), and remote points to the HTML help of another R installation.

help.start()                   # the HTML help system in the browser
help.start(update = TRUE)      # rebuild the package index first

Searching the help system

help() needs a name. The functions in this section find the name. They cast progressively wider nets, in the words of the R project’s own Getting Help with R page: apropos() looks at the names of the objects visible in the session, find() says where one exact name lives, help.search() (and ??) looks at the aliases, concepts and titles of every installed package, and RSiteSearch() searches the documentation of CRAN on the project’s server.

??pattern is help.search("pattern"), and field??pattern restricts the search to one field. Its arguments are:

  • fields: which parts of the help database to search, from "name", "title", "alias", "concept" and "keyword" (any abbreviation). The default is alias, concept and title. The concepts of a page are its \concept entries and the keywords outside the standard list; the standard keywords are listed in the file KEYWORDS of R.home("doc").

  • package: restrict the search to the named packages (NULL searches all installed ones, which on a machine with many packages takes noticeably longer).

  • agrep: fuzzy matching. With the default NULL, a pattern made only of letters, digits, spaces and dashes is matched approximately via agrep(), unless it has fewer than five characters; any other pattern, or a short one, is a regular expression. agrep = FALSE switches fuzzy matching off.

  • ignore.case (default TRUE), types ("help", "vignette" and "demo", in the order in which the results are shown), keyword, whatis and apropos (arguments that search one field only) and rebuild (rebuild the help database, which is otherwise kept in memory for the session and rebuilt when the search path or lib.loc changes).

The script shows a typing mistake that fuzzy matching forgives, a three-letter pattern that is a regular expression, the same mistake with fuzzy matching off, and the two functions that search names. The search pager is set again so that the result can be trimmed.

# Search results are shown by the pager, as help pages are: make it print.
options(pager = \(files, ...) writeLines(readLines(files)))

# Search the help system: fuzzy matching tolerates typing mistakes.
hs <- help.search("lenear model", package = "stats", types = "help")
x <- capture.output(print(hs))
cat(head(x[nzchar(x)], 9L), sep = "\n")
#> Help files with alias or concept or title matching ‘lenear model’ using
#> fuzzy matching:
#> stats::anova.glm        Analysis of Deviance for Generalized Linear
#>                         Model Fits
#> stats::anova.lm         ANOVA for Linear Model Fits
#> stats::anova.mlm        Comparisons between Multivariate Linear Models
#> stats::family.glm       Accessing Generalized Linear Model Fits
#> stats::family.lm        Accessing Linear Model Fits
#> stats::glm              Fitting Generalized Linear Models

# Patterns shorter than five characters are regular expressions, not fuzzy.
hs <- help.search("csv", package = "utils", fields = "alias")
x <- capture.output(print(hs))
cat(head(x[nzchar(x)], 7L), sep = "\n")
#> Help files with alias matching ‘csv’ using regular expression matching:
#> utils::read.table       Data Input
#>   Aliases: read.csv, read.csv2
#> utils::write.table      Data Output
#>   Aliases: write.csv, write.csv2
#> Type '?PKG::FOO' to inspect entries 'PKG::FOO', or 'TYPE?PKG::FOO' for
#> entries like 'PKG::FOO-TYPE'.

# agrep = FALSE turns fuzzy matching off.
x <- capture.output(print(help.search("lenear", package = "stats",
                                      agrep = FALSE)))
cat(x, sep = "\n")
#> No vignettes or demos or help files found with alias or concept or
#> title matching ‘lenear’ using regular expression matching.

# apropos() matches object names on the search path with a regular expression.
apropos("^read\\.")
#>  [1] "read.csv"     "read.csv2"    "read.dcf"     "read.delim"   "read.delim2"
#>  [6] "read.DIF"     "read.fortran" "read.ftable"  "read.fwf"     "read.socket"
#> [11] "read.table"
apropos("^read", mode = "function") |> length()
#> [1] 18
apropos("GLM")
#> [1] "glm"           "glm.control"   "glm.fit"       "predict.glm"
#> [5] "residuals.glm" "summary.glm"
apropos("GLM", ignore.case = FALSE)
#> character(0)

# find() says where one exact name lives; numeric = TRUE gives the position.
find("read.csv")
#> [1] "package:utils"
find("read.csv", numeric = TRUE)
#> package:utils
#>             5
find("sd")
#> [1] "package:stats"
find("no_such_function")
#> character(0)

apropos() and find() share one help page. apropos("read") returns the names, sorted, of the objects on the search path whose names match a regular expression, without regard to case; mode = "function" keeps only functions and where = TRUE adds the position on the search path. find() is stricter: by default (simple.words = TRUE) it matches whole names, always with case sensitivity, and answers "in which attached package or environment is this name?" (numeric = TRUE returns positions in the search path instead of names; the position of utils is 5 in an Rscript session, as the output shows). The ones that the search path hides are found with getAnywhere() in the next section.

RSiteSearch() sends a query to the search engine at https://search.r-project.org/ and opens the result in a browser. It searches the R manuals, the help pages of the base and CRAN packages, vignettes, package NEWS, package READMEs and Task Views; restrict chooses among eight areas ("functions", "descriptions", "news", "Rfunctions", "Rmanuals", "READMEs", "views" and "vignettes"), words chooses between all and any of the words, and braces or escaped quotes make a phrase. It needs a network and a browser, so it is shown as a fragment.

RSiteSearch("{generalized linear model}")                 # a phrase, all areas
RSiteSearch("read csv", restrict = "Rfunctions")          # base R help pages only
RSiteSearch("csv", restrict = c("functions", "vignettes"), words = "any")

The same server hosts the pages that the Source: lines of this section link to. The URL of a base-package help page has the shape https://search.r-project.org/R/refmans/<package>/html/<Rd-name>.html, and the Rd name is the name from the first line of the page, not the name of the function: read.csv is .../utils/html/read.table.html, summary.data.frame is .../base/html/summary.html and set.seed is .../base/html/Random.html. A CRAN package has the shape https://search.r-project.org/CRAN/refmans/<package>/html/<topic>.html, and the directory CRAN/refmans/ itself is not a page (it answers 403 Forbidden), so a link to a CRAN package’s reference has to name a topic. The older HTML manual at stat.ethz.ch, which the R FAQ still mentions in entry 2.7, lags behind the current release.

Inspecting objects

Help describes what the author intended; the object shows what R holds. Four functions answer "what is this?" and "where did it come from?".

  • args(f) returns a function with the same arguments as f and a NULL body, so printing it is a compact way to see the signature. formals(f) gives the arguments and their defaults as a list.

  • str(x) prints the structure of any object compactly: the class, the dimensions and the first values. On a data frame it is the quickest check that the columns have the types expected, and it is the first thing to paste into a question.

  • Typing the name of a function prints its source. This works for closures written in R; a function that calls compiled code shows the call (.Internal, .Call), and the C code is in the source of R. R FAQ 7.40 ("How do I access the source code for a function?") sends the reader to the article "Accessing the sources" in R News for the whole story.

  • methods(), getS3method() and getAnywhere() find what the name does not show. Many S3 methods live in namespaces and are not exported, so typing summary.data.frame is not enough, and R FAQ 7.26 ("Where have all the methods gone?") tells the reader to use getS3method("[", "terms") for an S3 method and pkg:::name for an unexported function. getAnywhere() reports every place a name is found, including registered S3 methods. An asterisk after a method’s name in the methods() listing means that it is not visible without ::: or getS3method().

books <- read.csv("books.csv")

args(read.csv)
#> function (file, header = TRUE, sep = ",", quote = "\"", dec = ".",
#>     fill = TRUE, comment.char = "", ...)
#> NULL
formals(read.csv)$sep
#> [1] ","
str(books)
#> 'data.frame':	16 obs. of  6 variables:
#>  $ title : chr  "The Dispossessed" "Pride and Prejudice" "  the quiet streets " "Loud Roofs" ...
#>  $ author: chr  "Ursula K. Le Guin" "Jane Austen" "Mara Quill" "Mara Quill" ...
#>  $ isbn  : chr  "978-0-306-40615-7" "978-0-14-143951-8" "9780001000100" "978-0-00-200029-1" ...
#>  $ year  : int  1974 1813 2019 2021 2016 2008 NA 1999 2012 2023 ...
#>  $ genre : chr  "Science fiction" "Classic" "Fiction" "fiction" ...
#>  $ pages : int  387 432 214 198 301 NA 96 280 352 256 ...

# Typing a name prints its source. Drop the bytecode address, which changes.
src <- capture.output(print(sd))
src[!grepl("^<bytecode", src)]
#> [1] "function (x, na.rm = FALSE) "
#> [2] "sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x), "
#> [3] "    na.rm = na.rm))"
#> [4] "<environment: namespace:stats>"

# S3 methods are hidden in namespaces: methods() lists them, getS3method()
# and getAnywhere() find them (R FAQ 7.26 and 7.40).
m <- methods("summary")
head(format(m), 6L)
#> [1] "summary.aov"                    "summary.aovlist*"
#> [3] "summary.aspell*"                "summary.check_packages_in_dir*"
#> [5] "summary.connection"             "summary.data.frame"
head(attr(m, "info"), 3L)
#>                 visible                            from generic  isS4
#> summary.aov        TRUE                           stats summary FALSE
#> summary.aovlist   FALSE registered S3method for summary summary FALSE
#> summary.aspell    FALSE registered S3method for summary summary FALSE
args(getS3method("summary", "data.frame"))
#> function (object, maxsum = 7L, digits = max(3L, getOption("digits") -
#>     3L), ...)
#> NULL
where <- getAnywhere("summary.data.frame")
where$where
#> [1] "package:base"
#> [2] "registered S3 method for summary from namespace base"
#> [3] "namespace:base"
where$visible
#> [1]  TRUE FALSE FALSE

The result of str(books) also shows what read.csv made of the file: character columns for the text, integer columns for year and pages with NA where the field was empty. The <bytecode> line that the console prints under a function is an address that changes from run to run, which is why the script removes it. Do not call unexported functions in code you ship: the FAQ warns that they are unexported for a reason and may change without notice.

Examples, demos and vignettes

The help system has three kinds of runnable material, ordered from the smallest to the largest.

example() runs the Examples section of a help page. Its arguments are topic, package, echo (show the code as well as the results, default TRUE), give.lines (return the lines of code instead of running them), local (evaluate in a local environment, so that the objects do not appear in the workspace), setRNG (save the random-number state, set the state that R CMD check uses and restore it afterwards), ask (pause before each plot), prompt.prefix, run.dontrun and run.donttest. The authors of a page can mark parts of its examples: \dontrun encloses code that must not run (because it needs a network, takes long, or would modify something), \dontshow encloses code that the page does not display but that checks and example() run, and \donttest encloses code that should run but not during package checking. example() skips \dontrun by default and skips \donttest unless run.donttest is true; its default is interactive(). R 4.4.0 added a \dontdiff tag, which only adds special comments to the code that example() runs (for testing the output) and changes neither what is run nor what the help page shows. The prompt shown before each line is the topic abbreviated to six letters (prompt.prefix), aprops> for apropos.

# example() runs the Examples section of a help page. apropos has \dontrun
# and \donttest parts; the echoed lines start with the prompt "aprops>".
out <- capture.output(example(apropos, ask = FALSE))
cat(head(out[nzchar(out)], 8L), sep = "\n")
#> aprops> require(stats)
#> aprops> ## Not run: apropos("lm")
#> aprops> apropos("GLM")                      # several
#> [1] "glm"           "glm.control"   "glm.fit"       "predict.glm"
#> [5] "residuals.glm" "summary.glm"
#> aprops> apropos("GLM", ignore.case = FALSE) # not one
#> character(0)
#> aprops> apropos("lq")

# \dontrun code is shown as a comment unless run.dontrun = TRUE, and
# \donttest code is skipped unless run.donttest is TRUE (interactive() is
# the default, so it is skipped here: its lines are echoed as "##D").
cat(grep("Not run|No test", out, value = TRUE), sep = "\n")
#> aprops> ## Not run: apropos("lm")
#> aprops> ## Not run: apropos(".", mode = "list")  # includes many datasets
#> aprops> ## No test:
#> aprops> ## End(No test)
out <- capture.output(example(apropos, run.dontrun = TRUE, ask = FALSE))
cat(grep("apropos\\(\"lm\"\\)", out, value = TRUE), sep = "\n")
#> aprops> apropos("lm")

# demo() lists the demonstrations of the loaded packages as a packageIQR.
demos <- demo(package = "stats")
class(demos)
#> [1] "packageIQR"
demos$results[, "Item"]
#> [1] "glm.vr" "lm.glm" "nlm"    "smooth"

# vignette() lists the long-form guides of installed packages.
v <- vignette(package = "dplyr")
data.frame(item = v$results[, "Item"],
           title = sub(" \\(source.*$", "", v$results[, "Title"])) |>
  head(4L)
#>       item                  title
#> 1  colwise Column-wise operations
#> 2     base       dplyr <-> base R
#> 3 grouping           Grouped data
#> 4    dplyr  Introduction to dplyr
v1 <- vignette("grid", package = "grid")
class(v1)
#> [1] "vignette"
c(v1$Package, v1$Topic, v1$PDF)
#> [1] "grid"     "grid"     "grid.pdf"
vignette(package = "grid")$results[, "Item"]
#>  [1] "moveline"    "displaylist" "interactive" "frame"       "grid"
#>  [6] "locndimn"    "sharing"     "nonfinite"   "saveload"    "rotated"
#> [11] "grobs"       "viewports"   "plotexample"

demo() runs longer scripts that are kept apart from the help pages. demo() lists those of the loaded packages as an object of class packageIQR; demo(package = "stats") lists those of one package, here glm.vr, lm.glm, nlm and smooth. A demo is run by name, and ask pauses at each page. Demos are stored under the demo directory of a package and are meant to be watched, not read; most need a graphics device.

demo()                                    # demos of the loaded packages
demo(package = "stats")                   # demos of one package
demo(lm.glm, package = "stats", ask = FALSE)   # run one without pausing

vignette() lists and opens vignettes, the long-form guides that packages ship (for how to write one, see Documentation with Rd, roxygen2 and Vignettes). vignette() with no topic lists the vignettes of all installed packages (all = TRUE, the default; all = FALSE restricts it to the attached packages), and vignette(package = "grid") lists those of one package. vignette("grid", package = "grid") returns an object of class vignette without opening it: the print method opens a viewer, a PDF viewer or a browser, which is why the script above stores it. The vignette name is the base name of the file, not its title, and a name used by two packages (grid is both a grid and a lattice vignette) needs the package argument or the form vignette(grid::grid). edit(v) opens the code of a vignette for editing. RShowDoc("frame", package = "grid") shows a rendered vignette, and browseVignettes() lists the vignettes in a browser, with links to the rendered document, the source and the extracted R code:

browseVignettes()                    # all installed packages, in a browser
browseVignettes("dplyr")             # one package
vignette("dplyr", package = "dplyr") # open one
RShowDoc("frame", package = "grid")  # a rendered vignette, pdf or html

The vignettes of a package are also listed on its CRAN page and its website (dplyr’s are at https://dplyr.tidyverse.org/articles/), so a package that is not installed can still be read before it is.

The manuals and the R FAQ

R ships with six manuals and an FAQ. They describe the system as a whole, which no single help page can, and they are the primary source for this section: each page of the section names the manual node that it derives from in its Source: lines. All of them are published for the current release under https://cran.r-project.org/doc/manuals/r-release/; the manuals are cited with the DOI 10.32614/R.manuals, which is also what citation() returns since R 4.6.0. Inside R, RShowDoc("R-intro") opens one, in the format given by its type ("pdf" in a batch run, "html" in an interactive one, or "txt").

Manual What it covers Where this section uses it

An Introduction to R (R-intro)

A tour of the language and its statistics: vectors, arrays, lists and data frames, reading data, distributions, statistical models, graphics, packages. Section 1.7, "Getting help with functions and features", is the manual’s version of this page.

Getting Started, Atomic Vectors and Types, Data Frames, Statistical Models, Base Graphics and Devices

The R Language Definition (R-lang)

The semantics: types and objects, evaluation, scoping and environments, argument matching and lazy evaluation, S3 dispatch, language objects, the parser and the lexical rules.

Syntax and Lexical Structure, Scoping, Environments and Closures, Lazy Evaluation and Promises, Language Objects and Quoting

R Data Import/Export (R-data)

Importing and exporting data: read.table and its relatives, fixed-width files, connections, other statistical systems, databases, binary formats.

Reading and Writing Text Data, Connections and the File System, Databases with DBI

R Installation and Administration (R-admin)

Installing R on each platform, add-on packages and libraries, repositories, locales and message translation, BLAS and LAPACK.

Getting Started, Packages, Libraries and Namespaces, Encodings, Locales and Internationalization

Writing R Extensions (R-exts)

Creating packages (DESCRIPTION, NAMESPACE, R CMD check), the Rd format, vignettes, profiling and debugging, and the interface to C, C++ and Fortran.

Creating Packages, Documentation with Rd, roxygen2 and Vignettes, Publishing to CRAN, Interfacing C, C++ and Fortran

R Internals (R-ints)

How R is built: the structure of its objects (SEXPs), environments, promises, copying and reference counting, lazy loading, .Internal against .Primitive. For readers who want to know why, not just how.

Memory and Copy Semantics, OOP Overview and Base Types (asides only)

R FAQ

Frequently asked questions in nine chapters. Chapter 2 (R Basics) lists the documentation and the mailing lists, chapter 5 the add-on packages, chapter 7 (R Miscellanea) the gotchas that this section quotes by number, and chapter 9 how to report a bug.

Idioms and Common Pitfalls and the page of each concept

R for Windows FAQ and R for macOS FAQ

The features specific to each port: installation, Rtools, the Windows console and the R.app GUI.

Getting Started

RShowDoc() finds the six manuals, "NEWS", "COPYING" (the licence), "FAQ" (also "R-FAQ") and the other files in the documentation directory of the installation; only on Windows is the R for Windows FAQ available as "rw-FAQ". With package = it looks in the doc directory of an installed package, which is where vignettes live. The script in the next section lists the files that exist in the container’s installation. Which formats of the manuals an installation contains depends on how R was built, so a missing PDF is not an error of R but of the build. The R FAQ also lists books by R Core members in entry 2.7, "What documentation exists for R?", and the annotated bibliography of R-related publications that the project keeps in BibTeX format.

RShowDoc("R-intro")                  # pdf in a batch run, html when interactive
RShowDoc("R-lang", type = "html")    # choose the format
RShowDoc("FAQ", type = "txt")        # the R FAQ as text, through the pager
RShowDoc("NEWS")                     # the NEWS file of this R

The project’s page Getting Help with R ties these together, and Other documentation on the same site lists the contributed documents.

News, citation and version

Three questions about R itself have a function each. Which version is this: R.version.string or getRversion(), which can be compared with a string such as getRversion() >= "4.6.0". What changed: news(), or RShowDoc("NEWS"), or the online NEWS of the current release (the development version has its own NEWS of R-devel). And how to cite R: citation(). news(query, package = "R") builds a data base of the news since R 4.0.0 ("R-3" and "R-2" give the older series) with the columns Version, Date, Category, Text and HTML; the query is an expression over those columns. news(package = "dplyr") reads the NEWS file of an installed package in the same way. The script below also prints sessionInfo(), the first thing any report needs, with the platform lines removed because they differ on every machine.

# The files that RShowDoc() can open sit in R.home("doc") of an installation;
# which formats of the manuals exist depends on how R was built.
list.files(R.home("doc"), pattern = "^[A-Z]+$")
#> [1] "AUTHORS"    "COPYING"    "COPYRIGHTS" "FAQ"        "KEYWORDS"
#> [6] "NEWS"       "RESOURCES"  "THANKS"
list.files(file.path(R.home("doc"), "manual"), pattern = "^R-.*html$")
#> [1] "R-admin.html" "R-data.html"  "R-exts.html"  "R-FAQ.html"   "R-intro.html"
#> [6] "R-ints.html"  "R-lang.html"

# How to cite R, and which R this is.
citation()
#> To cite R in publications use:
#>
#>   R Core Team (2026). _R: A Language and Environment for Statistical
#>   Computing_. R Foundation for Statistical Computing, Vienna, Austria.
#>   doi:10.32614/R.manuals <https://doi.org/10.32614/R.manuals>.
#>   <https://www.R-project.org/>.
#>
#> A BibTeX entry for LaTeX users is
#>
#>   @Manual{,
#>     title = {R: A Language and Environment for Statistical Computing},
#>     author = {{R Core Team}},
#>     organization = {R Foundation for Statistical Computing},
#>     address = {Vienna, Austria},
#>     year = {2026},
#>     doi = {10.32614/R.manuals},
#>     url = {https://www.R-project.org/},
#>   }
#>
#> We have invested a lot of time and effort in creating R, please cite it
#> when using it for data analysis. See also ‘citation("pkgname")’ for
#> citing R packages.
R.version.string
#> [1] "R version 4.6.1 (2026-06-24)"
getRversion() >= "4.6.0"
#> [1] TRUE

# NEWS since 4.0.0 is a data frame of class news_db; query it with an
# expression over its columns.
db <- news(Version >= "4.6.0", package = "R")
names(db)
#> [1] "Version"  "Date"     "Category" "Text"     "HTML"
unique(db$Version)
#> [1] "4.6.1" "4.6.0"
unique(db$Category)[1:3]
#> [1] "New Features"                     "Bug Fixes"
#> [3] "Significant User-Visible Changes"
hit <- db[grepl("%notin%", db$Text, fixed = TRUE), ]
hit$Version
#> [1] "4.6.0"
hit$Category
#> [1] "New Features"
substr(gsub("\\s+", " ", hit$Text[[1L]]), 1L, 70L)
#> [1] "x %notin% table newly in base is an idiom for !(x %in% table) and prov"

# sessionInfo() for a bug report: print it without the locale and drop the
# lines that name the platform, the operating system and the linear algebra
# libraries (they differ on every machine).
info <- capture.output(print(sessionInfo(), locale = FALSE))
drop <- grepl("^(Platform|Running|Matrix|BLAS|LAPACK)", info) | !nzchar(info)
cat(info[!drop], sep = "\n")
#> R version 4.6.1 (2026-06-24)
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base
#> loaded via a namespace (and not attached):
#> [1] compiler_4.6.1 tools_4.6.1

citation() prints a text citation and a BibTeX entry; its year is the release year of the version in use, and the DOI is 10.32614/R.manuals (R FAQ 2.8, "Citing R"). citation("dplyr") does the same for a package. sessionInfo() reports the R version, the operating system, the locale, the attached and loaded packages and their versions; print(sessionInfo(), locale = FALSE) omits the locale and the time zone. The posting guide asks for it whenever behaviour is surprising, with full version numbers rather than 4.6.

Community resources

Everything above ships with R or lives on the project’s own servers. The rest is maintained by the community; it is useful, and each item says what it is.

CRAN Task Views (https://cran.r-project.org/web/views/) are short documents, one per topic, that name the CRAN packages relevant to it. They are guidance, not endorsements: the page says the views are not meant to name the best package for a task. The ctv package (a CRAN package, not part of base R; version 1.0-1 at the check date, not installed in the container and so not run here) installs them from R: ctv::available.views() lists them, ctv::ctv("Econometrics") shows one and ctv::install.views("Econometrics") installs its packages.

search.r-project.org is the project’s search server, the one behind RSiteSearch(); it indexes the manuals and the base and CRAN help pages and serves them at the URL shapes shown above. The R Journal (https://journal.r-project.org/) is the refereed, open-access journal of the R Foundation, with articles of up to 20 pages on packages, applications and teaching; its articles describe packages, applications of R and teaching resources. The R Blog (https://blog.r-project.org/) carries posts by R Core members and contributors about the project and its infrastructure.

The mailing lists are described in R FAQ 2.9, "What mailing lists exist for R?", and on the project’s mailing lists page. They are operated through the Mailman web interface at https://stat.ethz.ch/mailman/listinfo/.

List Purpose Notes

R-help

The main list: problems and solutions in using R, including packages in the standard distribution and on CRAN, and nice examples and benchmarks.

Meant for people who use R to solve problems and may not be programmers. Not for homework or basic statistics.

R-devel

Questions and discussion about the development of R itself; proposals of new functionality and pre-testing of new versions.

Questions about C or C++, or too technical for R-help, belong here.

R-package-devel

Help with developing packages and with R CMD check.

Created in May 2015 (see Creating Packages). Cross-posting to R-devel as well is considered impolite.

R-announce

Moderated; major announcements about R and new code. Low volume.

Its messages are gatewayed into R-help, so subscribers of R-help need not subscribe.

R-packages

Moderated; announcements of new or enhanced contributed packages.

Gatewayed into R-help as well.

R-SIG lists

Special-interest groups: R-SIG-Mac, R-SIG-Debian, R-SIG-Fedora, R-SIG-mixed-models and others.

A question specific to a platform or a method is likelier to be answered there.

Read the posting guide before sending anything to a list. It asks the sender to do the homework first (help.search("keyword") and apropos("keyword") with different keywords, the help pages, the NEWS file and the FAQ), to use an informative subject line, to post in plain text without HTML, to give the full version of R and the platform, to include the output of sessionInfo() when behaviour is surprising, and to supply a small example that others can run. Bugs in a contributed package go to the package’s maintainer, whom maintainer("pkg") names. Stack Overflow (tag r) and the Posit Community forum (https://forum.posit.co/) are general question-and-answer sites for R users, outside the R Project; the same advice about examples applies there.

The R Development Guide (https://contributor.r-project.org/rdevguide/), written by the R Contribution Working Group, is for people who want to contribute to R itself rather than use it. It covers the R-patched and R-devel versions, issue tracking, reporting bugs, submitting feature requests, finding the source, the lifecycle of a patch, documenting, message translation and testing pre-release versions, with a chapter on where to get help.

Asking well: reproducible examples and bug reports

A question that others can run is answered; one that they cannot is not. A reproducible example is the smallest piece of code that starts from nothing and shows the problem, with the data inside it. The posting guide and R FAQ 9.2 ("How to report a bug") ask for the same things: the exact commands, starting from a clean session (R --vanilla ignores the site profile and the saved workspace), the version of R and the platform, and a statement of the facts rather than a guess about the cause. The tools in base R are dput(), which prints an expression that recreates an object, set.seed(), which makes random numbers repeatable, and sessionInfo(). The posting guide, written when dump("x", file = stdout()) was the usual tool, still recommends that; dput() does the same job for one object. The script reduces the page counts of the Shelf to three rows.

books <- read.csv("books.csv")

# The question: why does mean() return NA for the page counts?
mean(books$pages)
#> [1] NA

# Shrink the problem to the columns and rows that show it, and print the
# result with dput() so that others can paste it into their own session.
small <- books[c(5L, 6L, 7L), c("title", "pages")]
dput(small)
#> structure(list(title = c("Midnight Ledger", "A Map of Salt",
#> "Garden of Small Fires"), pages = c(301L, NA, 96L)), row.names = 5:7, class = "data.frame")

# Pasting that into a fresh session rebuilds the same data frame.
small_again <- structure(
  list(
    title = c("Midnight Ledger", "A Map of Salt", "Garden of Small Fires"),
    pages = c(301L, NA, 96L)
  ),
  row.names = 5:7, class = "data.frame"
)
identical(small, small_again)
#> [1] TRUE

# Fix random numbers with set.seed(), so that a sample is the same for all.
set.seed(282)
sample(nrow(books), 3L)
#> [1]  8 13 14

# The minimal example with its answer, and the facts that a report needs.
mean(small$pages, na.rm = TRUE)
#> [1] 198.5
R.version.string
#> [1] "R version 4.6.1 (2026-06-24)"
packageVersion("dplyr")
#> [1] ‘1.2.1’

# Who maintains the code, and where do its bugs go (bug.report() reads this).
maintainer("stats")
#> [1] "R Core Team <do-use-Contact-address@r-project.org>"
packageDescription("dplyr")$BugReports
#> [1] "https://github.com/tidyverse/dplyr/issues"

The community package reprex (not part of base R and not installed in the container, so this block is a fragment) wraps the steps: it takes code from the clipboard or an expression, runs it with rmarkdown::render(), and returns the code with its output as comments or Markdown, ready to paste into a GitHub issue, Stack Overflow or Slack. Its comment argument defaults to the same #> marker as the examples of this section (reprex 2.1.1 at the check date), and its documentation recommends installing xclip or xsel on Linux so that it can reach the clipboard.

# reprex is a community package (CRAN); the code below is a fragment.
reprex::reprex({
  x <- c(301L, NA, 96L)
  mean(x)
})

For a real bug in R itself, R FAQ 9.1 ("What is a bug?") defines what counts: a crash or an operating-system error that is not the user’s own call into compiled code, a command from the documentation that does the wrong thing, or a command that takes forever when it should not. Unexpected comparisons of decimal numbers (0.1 + 0.2 != 0.3) are not bugs. Then check whether it is known: the search facility of R’s Bugzilla (bugs.R-project.org), the development NEWS, and the current R-patched or R-devel build. Bugs in contributed packages go to the package maintainers first and only reach the R bug tracker through them. Since 2016 only "members", including all who have previously submitted bugs, can submit new bugs on the Bugzilla (R FAQ 9.2). Two functions in utils start the process from R: help.request() walks through a checklist before preparing a post to R-help with the session information in it, and bug.report() opens the bug tracker for R, or the tracker or an e-mail template for a package named with package =. The project’s Bug Reporting in R page adds that bug.report() is disabled in some IDEs, in which case the place to report is found in packageDescription("pkg") (the BugReports field, shown in the script above).

help.request()                       # checklist, then a template post to R-help
bug.report()                         # R itself: opens the bug tracker
bug.report(package = "dplyr")        # a package: its BugReports page or an e-mail

Common errors and warnings

The help functions rarely stop a script; most report that nothing was found, and some of the messages are easy to misread. The script catches each one and shows the text R produces. Messages that R prints with quotes use directional quotes in a UTF-8 locale.

# Each call fails or warns; tryCatch() turns the condition into its text.
text_of <- \(expr) {
  tryCatch(
    {
      expr
      "no condition"
    },
    error = \(e) paste("Error:", conditionMessage(e)),
    warning = \(w) paste("Warning:", conditionMessage(w))
  )
}

# 1. A topic that does not exist is not an error: help() prints two lines.
capture.output(help("foo"))
#> [1] "No documentation for ‘foo’ in specified packages and libraries:"
#> [2] "you could try ‘??foo’"

# 2. example() warns about a missing topic; a missing package is an error.
writeLines(text_of(example(foo)))
#> Warning: no help found for ‘foo’
writeLines(text_of(example("lm", package = "nopkg")))
#> Error: there is no package called ‘nopkg’

# 3. A space in the name makes the question a syntax error (parse() shows
# what the console reports as: Error: unexpected symbol in "?my data").
writeLines(text_of(parse(text = "?my data")))
#> Error: <text>:1:5: unexpected symbol
#> 1: ?my data
#>         ^

# 4. vignette(), demo(), RShowDoc() and help(package =) fail in their own way.
writeLines(text_of(vignette("nonexistent")))
#> Warning: vignette ‘nonexistent’ not found
writeLines(text_of(demo("nodemo")))
#> Error: No demo found for topic ‘nodemo’
writeLines(text_of(RShowDoc("nodoc")))
#> Error: document not found
writeLines(text_of(help(package = "nopkg")))
#> Error: there is no package called ‘nopkg’

# 5. apropos() takes a regular expression, so a bare bracket is invalid.
writeLines(text_of(apropos("[")))
#> Warning: TRE pattern compilation error 'Missing ']''
tryCatch(suppressWarnings(apropos("[")), error = \(e) conditionMessage(e))
#> [1] "invalid regular expression '[', reason 'Missing ']''"
apropos("\\[\\[", mode = "function") |> head(3L)
#> [1] "[["            "[[.data.frame" "[[.Date"
What R prints Cause What to do

No documentation for ‘foo’ in specified packages and libraries: and you could try ‘??foo’

help() found no page with that alias in the loaded packages or the libraries. This is output, not an error condition, so tryCatch() does not see it.

Check the spelling and the case; try ??foo, or help("foo", try.all.packages = TRUE) when the package is installed but not loaded.

Warning: no help found for ‘foo’ (console: In example(foo) : no help found for ‘foo’)

example() could not find a help page for the topic, so there are no examples to run.

The same: the topic name is the alias of a page, not the name of every function.

there is no package called ‘nopkg’

help(package = ), example(package = ) and vignette(package = ) need an installed package.

install.packages("nopkg") first, or check .libPaths() and the package’s name.

<text>:1:5: unexpected symbol (console: Error: unexpected symbol in "?my data")

The topic contains a space, so R parses ?my data as two expressions.

Quote it: ?"my data" finds nothing, because a topic is an alias; use ??"my data" to search words.

vignette ‘nonexistent’ not found

A warning: no installed package has a vignette with that base name. The name is the file name, not the title.

vignette(package = "pkg") shows the names; give package =.

No demo found for topic ‘nodemo’

demo() has no demo with that name in the packages searched.

demo(package = "stats") lists them.

document not found

RShowDoc() does not know the name.

Use one of the manual names, "NEWS", "FAQ" or a file in a package’s doc directory.

TRE pattern compilation error 'Missing ']'', then invalid regular expression '[', reason 'Missing ']''

apropos() takes a regular expression; [ opens a character class.

Escape the bracket: apropos("\\[") is how the help page of apropos finds the extraction operators.

Pitfalls

  • The page name is not the function name. ?read.csv opens read.table; ?"+" opens Arithmetic; ?set.seed opens Random; the URL of the online page uses the page name. help() returns the path, and basename() of it is the name (see the table above). When the documentation of a name seems to be missing, search with ?? before concluding that it does not exist.

  • ? needs a name, not an expression. A space or an operator in the topic is a syntax error, or the wrong topic. Use quotes for operators and reserved words.

  • help(x) can use the value of x. If x holds a single string, the string is the topic (the help page documents this); write help("x") when the name itself is meant.

  • Help is searched in loaded packages first. A function in an installed package that is not loaded is invisible to ?name and apropos(); pkg::name, package = or try.all.packages = TRUE find it. R FAQ 7.29 explains the vocabulary: a package is a collection of code, data or documentation, a library is a directory where installed packages are kept, and library() loads a package from a library; R FAQ 7.30 adds that an installed package must still be loaded before its functions can be used.

  • The search index is kept for the session. help.search() keeps its database in memory and rebuilds it when lib.loc or the search path changes; rebuild = TRUE forces it.

  • Examples change the workspace. example() runs in the global environment unless local = TRUE, so it can overwrite an object of the same name; use local = TRUE while exploring.

  • The version matters. A function that does not exist in your help is not necessarily absent from the web. Check R.version.string and news(): for example %notin% is new in 4.6.0 (the script above found it in the NEWS), and many online answers predate it.

  • The R FAQ has entries from earlier eras. Entry 2.7 still points to stat.ethz.ch for the HTML manuals; the current release is under cran.r-project.org/doc/manuals/r-release/ and search.r-project.org.

Where older tutorials are outdated

Older material is not wrong about the commands, which still work, but about which to reach for first.

  • help.start() as the main entry. Tutorials written for the HTML help system open it first. It still works and is the right tool to browse the manuals and the package index offline, but every IDE and the ? operator reach the same pages, and R FAQ 7.24 records why old advice about its search engine no longer applies: since R 2.10.0 the browser search is an HTML interface to help.search(), where before it needed Java and JavaScript.

  • library(help = "pkg"). It still works and the posting guide still asks for its header output; help(package = "pkg") is the form documented on the help page and shows the same index.

  • RSiteSearch() and the sos package. The posting guide describes RSiteSearch() as searching R-help postings. The current help page lists eight areas, and the archive of the mailing lists is not among them. The sos package is a community alternative to RSiteSearch() that the project’s page Getting Help with R still lists next to it; the same page suggests pasting an error message into a search engine.

  • dump() for examples. The posting guide recommends dump("x", file = stdout()); dput(x) is the current habit, and reprex automates the rest.

  • R-help as the first stop. Older tutorials send every question to R-help. The lists remain the official channel for questions about R itself, and the posting guide still governs them, but the project’s own help page also lists Stack Overflow, and a question about a package belongs with the package’s maintainer or issue tracker (maintainer("pkg"), the BugReports field).

  • R-bugs by e-mail. The posting guide still speaks of the r-bugs address. Since 2016 reports are made on R’s Bugzilla, and only members can create them (R FAQ 9.2).

  • HTML against text help. Tutorials show whichever form their author’s platform used: HTML in a browser on Windows, plain text in a terminal on a Unix-alike. The content is the same Rd page, rendered as text, HTML or PDF by help_type.

  • stat.ethz.ch/R-manual as the manual URL. The FAQ still names it; the maintained online manuals are under cran.r-project.org/doc/manuals/r-release/ and the help pages under search.r-project.org/R/refmans/. For the changes since R 4.0, see What’s New and Migrating Older Code.