Emergency server help: get in touch

R Cheat Sheet: Vectors, Data Frames, Strings and Files

A compact reference for base R with tables for vectors, subsetting, data frames, functions, strings, files, error handling and quick statistics.

Published 7 min read

Short answer: In R, everything is a vector: c(3, 1, 2) builds one, operations apply element by element, and indexes start at 1. Assign with <-, subset with x[x > 1] or df[df$cpu > 50, ], loop less and use sapply, vapply or Map instead, chain steps with the native pipe |>, and write short functions as \(x) x + 1. Read data with read.csv(), catch errors with tryCatch(), and summarise with summary(), table() and aggregate().

The examples in this R cheat sheet were run with R 4.3.3 on 9 October 2026, using base R only. The current release is R 4.6.1; functions marked 4.4+ or later were checked against the R NEWS file.

Vectors and basic types

SyntaxWhat it doesExample
x <- c(3, 1, 2)Create a vector (= also assigns)ports <- c(80, 443)
5L, "a", TRUE, NA, NULLInteger, character, logical, missing value, nothingclass(5L) gives "integer"
1:5, seq(1, 10, by = 3)Sequencesseq_len(n) is safe when n is 0
rep(x, times = 2), rep(x, each = 2)Repeatrep(1:2, each = 2) gives 1 1 2 2
x * 2, x + yElement-wise arithmetic; shorter vectors recyclec(3, 1, 2) * 2
%/%, %%, ^Integer division, modulo, power7 %/% 2 is 3
sum, mean, max, range, cumsumSummaries; na.rm = TRUE skips NAmean(c(1, NA, 3), na.rm = TRUE)
sort, order, rev, uniqueorder returns positions, for sorting other thingsdf[order(-df$cpu), ]
%in%, any, all, whichMembership and tests (%notin% is in base from 4.6)which(x > 1)
ifelse(test, yes, no)Vectorised ififelse(x > 1, "big", "small")
is.na(), as.integer(), as.character()Test and convertas.numeric("abc") gives NA with a warning
factor(x, levels = …)Categorical data with fixed levelstable(f) counts per level
matrix(1:6, nrow = 2)Matrix (filled by column); %*% multipliesm[2, 3]

Never compare floating-point numbers with ==: 0.1 + 0.2 == 0.3 is FALSE. Use isTRUE(all.equal(a, b)).

Indexing and subsetting

SyntaxReturnsExample
x[2], x[c(1, 3)]Elements by position (1-based)x[length(x)] is the last
x[-1]Everything except position 1x[-(1:2)]
x[x > 1]Elements where a logical test is TRUElat[lat > 500]
v["b"]By namev <- c(a = 1, b = 2)
l[["key"]] vs l["key"]The element itself vs a one-element listcfg[["host"]]
l$keyShorthand for [["key"]]df$cpu
df[rows, cols]Data frame rows and columns; leave one blank for alldf[df$cpu > 50, c("host", "cpu")]
head(x, n), tail(x, n)First or last nhead(df, 3)

Data frames

FunctionWhat it doesExample
data.frame()Build a table from equal-length vectorsdata.frame(host = c("web01", "db01"), cpu = c(35, 55))
str(df), summary(df)Structure and per-column summariesFirst thing to run on new data
nrow, ncol, namesSize and column namesnames(df)
df$new <- …Add or replace a columndf$high <- df$cpu > 60
subset(df, cond, select = …)Filter rows and pick columnssubset(df, cpu > 50, select = c(host, cpu))
aggregate(y ~ g, data, FUN)Group and summariseaggregate(cpu ~ role, data = df, FUN = mean)
tapply(x, g, f)Apply a function per groupwith(df, tapply(cpu, role, max))
merge(a, b, by = "k")Join two data framesmerge(df, owners, by = "role")
rbind, cbindStack rows or columnsrbind(df1, df2)
split(x, g)List of pieces per groupsplit(df$cpu, df$role)
transform(df, …)Add computed columnstransform(df, cpu_frac = cpu / 100)
df |> subset(role == "web") |> nrow()
mtcars |> lm(mpg ~ wt, data = _) |> coef()   # _ placeholder must be a named argument

Lists, functions and the apply family

SyntaxWhat it doesExample
list(host = "web01", ports = c(80, 443))Container for mixed types, can nestl$meta$os
l$key <- NULLRemove an elementcfg$password <- NULL
f <- function(x, y = 2, ...) { … }Function with default and extra arguments; the last value is returnedgreet <- function(name, greeting = "Hello")
\(x) x + 1Short lambda (R 4.1+)sapply(1:3, \(i) i^2)
<<-Assign in an enclosing environment (closures)n <<- n + 1
missing(arg)Was an argument supplied?if (missing(b)) "no b"
match.arg(x, choices)Validate against allowed values, with partial matchingmatch.arg("med", c("low", "medium"))
lapply / sapplyApply over a list; return a list / simplifylapply(files, readLines)
vapply(x, f, integer(1))Like sapply, with a checked result typevapply(c("a", "bb"), nchar, integer(1))
Map, mapplyIterate over several vectors in parallelMap(\(a, b) a + b, 1:2, 3:4)
Reduce, FilterFold and filterFilter(\(n) n %% 2 == 0, 1:6)
apply(m, 1, f)Rows (1) or columns (2) of a matrixapply(m, 2, max)
do.call(f, list)Call with arguments from a listdo.call(rbind, pieces)
x %||% y (4.4+)y when x is NULLopts$timeout %||% 30

Control flow

SyntaxExample
if (…) { … } else if (…) { … } else { … }if (code >= 500) "server" else "ok"
for (h in hosts) { … }for (i in seq_along(x)) …
while (cond) { … }, repeat { … }repeat needs a break
next / breakSkip an iteration / leave the loop
switch(x, a = 1, b = 2, default)switch("db", web = 80, db = 3306, 0) gives 3306

if needs a single TRUE or FALSE. Use ifelse() or any()/all() when the condition is a vector, otherwise R 4.2+ raises an error.

Strings and regular expressions

FunctionWhat it doesExample
paste(a, b, sep = "-"), paste0()Join; collapse joins a vector into one stringpaste(hosts, collapse = ",")
sprintf()printf-style formatting, vectorisedsprintf("%-8s %5d", host, port)
format(x, big.mark = ",")Number formattingformat(1234567.891, big.mark = ",", nsmall = 2)
nchar, toupper, trimws, substrLength, case, trim, substringsubstr(s, 1, 5)
strsplit(s, ",")[[1]]Split (returns a list)strsplit("a,b,c", ",")[[1]]
startsWith, endsWithPrefix and suffix testsendsWith(f, ".log")
grepl(pat, x)TRUE/FALSE per elementgrepl("^web", hosts)
grep(pat, x, value = TRUE)Matching elements (grepv() in 4.5+ does the same)grep("db", hosts, value = TRUE)
sub / gsubReplace first / all; \\1 for groupssub("^(\\w+)\\..*$", "\\1", fqdn)
regmatches(x, gregexpr(pat, x))Extract all matchesregmatches(s, gregexpr("[0-9]+", s))[[1]]
fixed = TRUE, perl = TRUELiteral match / PCRE (lookarounds)grepl(".", x, fixed = TRUE)
r"(C:\path)"Raw string, no escaping (4.0+)Windows paths, regexes

R strings need double backslashes in patterns: "\\d+" is the regex \d+. A raw string such as r"(\d+)" avoids that.

Files, dates and running R from the shell

TaskCode
Read a CSVdf <- read.csv("hosts.csv") (stringsAsFactors is FALSE by default since 4.0)
Write a CSVwrite.csv(df, "out.csv", row.names = FALSE)
Lines of textreadLines(path) / writeLines(lines, path)
Appendcat("line\n", file = path, append = TRUE)
Save any R objectsaveRDS(df, "df.rds") then readRDS("df.rds")
Filesfile.exists, list.files(dir, pattern = "\\.csv$"), unlink(path), tempfile()
EnvironmentSys.getenv("HOME")
Datesas.Date("2026-10-09") + 30, format(d, "%d %b %Y")
Parse a log timeas.POSIXct("09/Oct/2026:10:00:00", format = "%d/%b/%Y:%H:%M:%S", tz = "UTC")
Time differencedifftime(t2, t1, units = "mins")
Run a commandsystem2("uptime", stdout = TRUE)

For server admins: Rscript runs R non-interactively, so it fits in cron jobs and pipelines: Rscript report.R, or one-liners such as Rscript -e 'summary(read.csv("latency.csv")$ms)'. Install the interpreter from the distribution (dnf install R from EPEL on AlmaLinux, apt install r-base on Debian and Ubuntu).

Errors and conditions

res <- tryCatch({
  stop("bad port")
}, error = function(e) {
  paste("caught:", conditionMessage(e))
}, finally = {
  cat("cleanup\n")
})
print(res)   # "caught: bad port"
FunctionWhat it does
stop(msg), warning(msg), message(msg)Signal an error, a warning or a message (messages go to stderr)
tryCatch(expr, error = , warning = , finally = )Handle conditions; a caught warning stops the expression
withCallingHandlers() + invokeRestart("muffleWarning")Log a warning and carry on
try(expr, silent = TRUE)Returns an object of class try-error on failure
stopifnot("port must be numeric" = is.numeric(p))Assertions with custom messages
on.exit(close(con), add = TRUE)Cleanup when the function exits
errorCondition(msg, class = "configError")Custom condition class to catch by name

Quick statistics and plots

FunctionWhat it doesExample
summary(x)Min, quartiles, mean, maxsummary(lat)
quantile(x, c(0.5, 0.95))Percentilesp50 and p95 latency
sd, var, median, corSpread and correlationcor(mtcars$mpg, mtcars$wt)
table(x), prop.table()Counts and proportionssort(table(codes), decreasing = TRUE)
cut(x, breaks)Bin numbers into rangestable(cut(lat, c(0, 100, 500, Inf)))
lm(y ~ x1 + x2, data)Linear model; coef() and summary() on the resultlm(mpg ~ wt + hp, data = mtcars)
set.seed(1), sample, rnormReproducible random numberssample(1:10, 3)
hist, plot, boxplotBase graphicsWrap with png("out.png") … dev.off() on a headless server
lat <- c(120, 95, 300, 110, 2000, 130)
quantile(lat, c(0.5, 0.95))
#  50%  95%
#  125 1575

Official documentation (checked 9 October 2026): An Introduction to R · R Language Definition · R NEWS (release notes) · R manuals · The R Project

R Cheat Sheet at a glance

R Cheat Sheet – short answer
In short: A compact reference for base R with tables for vectors, subsetting, data frames, functions, strings, files, error handling and quick statistics.
R Cheat Sheet – what this guide covers
R Cheat Sheet: what this guide covers.

Related guides: Python Cheat Sheet: Syntax, Data Types and File Handling · Excel Cheat Sheet: Formulas, Dynamic Arrays and Shortcuts · SQL Cheat Sheet: MySQL, MariaDB and PostgreSQL Syntax.

Reading a lot of our guides? Go ad-free with srvScripts Pro for $6 a month. It also pays for new guides. Cancel any time.

Share this guide

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.