| Title: | Base Functions for the 'DescToolsX' Ecosystem |
|---|---|
| Description: | Provides the low level utilities on which the 'DescToolsX' ecosystem is built. Covered are data manipulation and reshaping, predicates for data inspection and validation, vector and string operations, handling of labels and metadata, and routines from number theory and combinatorics. All functions share a common naming and argument scheme and are implemented as S3 generics wherever several input types are meaningful, with performance critical parts written in C++. The package is self contained and can be used on its own, independently of the higher level packages of the suite. |
| Authors: | Andri Signorell [aut, cre] (ORCID: <https://orcid.org/0000-0003-4311-1969>), R Core Team [ctb], Hans W. Borchers [ctb], Daniel Chessel [ctb], Nicholas Cooper [ctb], Stephane Dray [ctb], Martin Elff [ctb], Michael Friendly [ctb], Friedrich Leisch [ctb], Thomas Lumley [ctb], Martin Maechler [ctb], Nick Sabbe [ctb], Karline Soetaert [ctb], Terry Therneau [ctb], Kevin Ushey [ctb], Jeremy VanDerWal [ctb], Bill Venables [ctb], Gregory R. Warnes [ctb], Daniel Wollschlaeger [ctb], Thomas W. Yee [ctb] |
| Maintainer: | Andri Signorell <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 0.1.19 |
| Built: | 2026-10-13 19:53:59 UTC |
| Source: | https://github.com/andrisignorell/bedrock |
The function duplicated() returns a logical vector indicating
which elements of x are duplicates, but it does not flag the first
occurrence of subsequently duplicated elements.
allDuplicated(x)allDuplicated(x)
x |
a vector of any type. |
allDuplicated returns a logical vector indicating all elements of
x that are involved in ties (i.e., have frequency > 1).
Note that allDuplicated flags all occurrences of tied values, not only
the duplicates beyond the first occurrence.
Consequently, !allDuplicated(x) can be used to identify elements of
x that appear exactly once.
Missing values are considered equal to each other, so multiple NAs
are flagged as ties. As the function builds on duplicated(),
it also works for data frames (row-wise) and matrices.
a logical vector of the same length as x.
duplicated() for identifying duplicate elements (excluding first
occurrences). unique() for extracting unique values. split() for grouping tied values. table() for counting frequencies.
Other data.equal:
allIdentical(),
compareDataFrames()
x <- c(1:10, 4:6) allDuplicated(x) # Compare with duplicated(): duplicated(x) # Elements appearing exactly once x[!allDuplicated(x)] # Identify and analyse ties x <- sample(letters[1:10], 20, replace = TRUE) ties <- split(x, x) # Number of tied groups sum(sapply(ties, length) > 1) # Sizes of tied groups sizes <- sapply(ties, length) sizes[sizes > 1] # Same via table() tab <- table(x) tab[tab > 1]x <- c(1:10, 4:6) allDuplicated(x) # Compare with duplicated(): duplicated(x) # Elements appearing exactly once x[!allDuplicated(x)] # Identify and analyse ties x <- sample(letters[1:10], 20, replace = TRUE) ties <- split(x, x) # Number of tied groups sum(sapply(ties, length) > 1) # Sizes of tied groups sizes <- sapply(ties, length) sizes[sizes > 1] # Same via table() tab <- table(x) tab[tab > 1]
Extends identical() to more than two objects. Returns
TRUE if all supplied objects are exactly identical, and
FALSE otherwise.
allIdentical(...)allIdentical(...)
... |
objects to compare. |
If zero or one object is supplied, the function returns TRUE.
Note that the objects themselves are compared, not their elements.
So allIdentical(list(A, B, C)) is TRUE, as a single
object is trivially identical to itself. Use
do.call(allIdentical, myList) to compare the elements of
a list.
logical scalar.
Other data.equal:
allDuplicated(),
compareDataFrames()
A <- LETTERS[1:5] B <- LETTERS[1:5] C <- LETTERS[1:5] E <- factor(LETTERS[1:5]) allIdentical(A, B, C) # TRUE allIdentical(A, B, C, E) # FALSE allIdentical(1, 1L) # FALSE (type matters)A <- LETTERS[1:5] B <- LETTERS[1:5] C <- LETTERS[1:5] E <- factor(LETTERS[1:5]) allIdentical(A, B, C) # TRUE allIdentical(A, B, C, E) # FALSE allIdentical(1, 1L) # FALSE (type matters)
Prepends (or inserts) a column of enumeration labels – lowercase or uppercase Roman numerals, or Arabic numbers.
appendEnum( x, type = c("roman-lcase", "roman-ucase", "arabic"), suffix = ". ", startWith = 1L, after = 0L, colName = NULL )appendEnum( x, type = c("roman-lcase", "roman-ucase", "arabic"), suffix = ". ", startWith = 1L, after = 0L, colName = NULL )
x |
a data.frame or matrix (vectors are coerced via |
type |
enumeration style: |
suffix |
text appended to each enumeration label. |
startWith |
first enumeration index. |
after |
position after which the column is inserted (see
|
colName |
optional name for the new column; |
x with an additional enumeration column.
Other data.append:
appendRowNames(),
appendX(),
multMerge()
d <- data.frame(x = 1:3, y = c("a", "b", "c")) appendEnum(d) appendEnum(d, type = "arabic", suffix = ") ") # insert after the first column instead of prepending appendEnum(d, after = 1L, colName = "no")d <- data.frame(x = 1:3, y = c("a", "b", "c")) appendEnum(d) appendEnum(d, type = "arabic", suffix = ") ") # insert after the first column instead of prepending appendEnum(d, after = 1L, colName = "no")
Adds the row names of a data.frame or matrix as a column.
appendRowNames(x, colName = "rowname", after = 0L, removeRowNames = TRUE)appendRowNames(x, colName = "rowname", after = 0L, removeRowNames = TRUE)
x |
a data.frame or matrix. |
colName |
name of the new column containing the row names. |
after |
position after which the column is inserted. Default is 0 (first column). |
removeRowNames |
logical; if TRUE, existing row names are removed. |
an object of the same class as x with the row names added
as a column. Note that for matrices the result is coerced to the common
mode, so appending (character) row names to a numeric matrix yields a
character matrix.
Other data.append:
appendEnum(),
appendX(),
multMerge()
dd <- data.frame(x = 1:5, y = 6:10, z = LETTERS[1:5], row.names = letters[1:5]) appendRowNames(dd)dd <- data.frame(x = 1:5, y = 6:10, z = LETTERS[1:5], row.names = letters[1:5]) appendRowNames(dd)
Generic function to append or insert elements to vectors, matrices, and data frames.
appendX(x, values, after = NULL, ...) ## Default S3 method: appendX(x, values, after = NULL, ...) ## S3 method for class 'matrix' appendX(x, values, after = NULL, rows = FALSE, newNames = NULL, ...) ## S3 method for class 'data.frame' appendX(x, values, after = NULL, rows = FALSE, newNames = NULL, ...) ## S3 method for class 'TOne' appendX(x, values, after = NULL, rows = TRUE, newNames = NULL, ...)appendX(x, values, after = NULL, ...) ## Default S3 method: appendX(x, values, after = NULL, ...) ## S3 method for class 'matrix' appendX(x, values, after = NULL, rows = FALSE, newNames = NULL, ...) ## S3 method for class 'data.frame' appendX(x, values, after = NULL, rows = FALSE, newNames = NULL, ...) ## S3 method for class 'TOne' appendX(x, values, after = NULL, rows = TRUE, newNames = NULL, ...)
x |
object to which values are appended. |
values |
values to insert into |
after |
position after which to insert. If |
... |
additional arguments. |
rows |
logical; if TRUE, insert rows instead of columns. Ignored for
vectors. Note that the method for |
newNames |
optional names for the inserted elements: column names when
inserting columns, row names when inserting rows. When inserting a column
into a data.frame without giving |
object of the same class as x.
Other data.append:
appendEnum(),
appendRowNames(),
multMerge()
# vectors appendX(1:5, 99, after = 2) # matrices: insert a column / a row m <- matrix(1:6, nrow = 2, dimnames = list(c("r1", "r2"), c("a", "b", "c"))) appendX(m, c(9, 9), after = 1, newNames = "z") appendX(m, 7:9, after = 1, rows = TRUE, newNames = "r1b") # data frames: insert a column / a row d <- data.frame(a = 1:3, b = 4:6) appendX(d, 7:9, after = 1, newNames = "z") appendX(d, list(a = 99, b = 88), after = 0, rows = TRUE)# vectors appendX(1:5, 99, after = 2) # matrices: insert a column / a row m <- matrix(1:6, nrow = 2, dimnames = list(c("r1", "r2"), c("a", "b", "c"))) appendX(m, c(9, 9), after = 1, newNames = "z") appendX(m, 7:9, after = 1, rows = TRUE, newNames = "r1b") # data frames: insert a column / a row d <- data.frame(a = 1:3, b = 4:6) appendX(d, 7:9, after = 1, newNames = "z") appendX(d, list(a = 99, b = 88), after = 0, rows = TRUE)
Clamps a confidence interval to the range of the parameter and opens the side that a one-sided interval leaves free. One implementation for the whole suite, so that every function reports a one-sided bound the same way.
applySides(ci, sides = "two.sided", lo = -Inf, hi = Inf)applySides(ci, sides = "two.sided", lo = -Inf, hi = Inf)
ci |
numeric vector of length two, the lower and upper bound in that
order. |
sides |
character string, one of |
lo, hi
|
the range of the parameter, not infinities by default in spirit but in signature. See Details. |
sides names the side carrying the finite bound:
"left"the informative bound is the lower one; the upper
one is opened to hi.
"right"the informative bound is the upper one; the lower
one is opened to lo.
lo and hi are the parameter's range, not infinities. Most
statistics are bounded, so reporting the open side at the boundary is the
ordinary case rather than an exception: a correlation opens to
, an association measure in to 0 or 1, Pearson's
to . Where the parameter really is unbounded,
Inf is passed and the usual half-line comes back. Some
statistics need one of each: Cronbach's alpha takes lo = -Inf and
hi = 1, a relative risk lo = 0 and hi = Inf.
The two-sided interval is clamped to as well, so an
interval can never claim a value the statistic cannot take.
a named numeric vector with the elements lci and
uci.
ci <- c(0.12, 0.58) applySides(ci, "two.sided", lo = 0, hi = 1) applySides(ci, "left", lo = 0, hi = 1) # uci opens to 1 applySides(ci, "right", lo = 0, hi = 1) # lci opens to 0 # an unbounded parameter opens to infinity applySides(c(-1.4, 2.6), "left", lo = -Inf, hi = Inf) # and one of each: Cronbach's alpha is bounded above only applySides(c(0.61, 0.94), "right", lo = -Inf, hi = 1) # the two-sided interval is clamped too applySides(c(-0.2, 1.3), "two.sided", lo = 0, hi = 1) # NA bounds survive applySides(c(NA, NA), "left", lo = -1, hi = 1)ci <- c(0.12, 0.58) applySides(ci, "two.sided", lo = 0, hi = 1) applySides(ci, "left", lo = 0, hi = 1) # uci opens to 1 applySides(ci, "right", lo = 0, hi = 1) # lci opens to 0 # an unbounded parameter opens to infinity applySides(c(-1.4, 2.6), "left", lo = -Inf, hi = Inf) # and one of each: Cronbach's alpha is bounded above only applySides(c(0.61, 0.94), "right", lo = -Inf, hi = 1) # the two-sided interval is clamped too applySides(c(-0.2, 1.3), "two.sided", lo = 0, hi = 1) # NA bounds survive applySides(c(NA, NA), "left", lo = -1, hi = 1)
xtabs Object to Array or MatrixConverts an object of class "xtabs" to a plain array or matrix by
dropping all additional classes such as "xtabs" and "table",
along with the call attribute.
## S3 method for class 'xtabs' as.array(x, ...) ## S3 method for class 'xtabs' as.matrix(x, ...)## S3 method for class 'xtabs' as.array(x, ...) ## S3 method for class 'xtabs' as.matrix(x, ...)
x |
an object of class |
... |
ignored. |
an array (or matrix in the two-dimensional case) with no additional classes.
Other data.coerce:
toBaseR(),
type-aliases
xt <- xtabs(~ cyl + gear, data = mtcars) class(as.matrix(xt)) # "matrix" "array"xt <- xtabs(~ cyl + gear, data = mtcars) class(as.matrix(xt)) # "matrix" "array"
A unified conversion utility for binary variables. Converts a logical, numeric, factor, or character vector to a binary numeric vector coded as 0 and 1.
asBinary(x, pos = NULL, warn = TRUE)asBinary(x, pos = NULL, warn = TRUE)
x |
a logical, numeric, integer, factor, or character vector. |
pos |
optional positive value. If supplied, observations equal to
|
warn |
logical. If |
For logical input, TRUE is mapped to 1 and FALSE
to 0.
For numeric input, values must already be 0 or 1 (or NA);
any other value raises an error.
For factor input, the vector must have exactly two levels. By
default the second level is coded as 1. Use pos to specify which
level should be coded as 1.
For character input, the vector must have exactly two distinct
non-missing values. By default the alphabetically second value is coded
as 1. The same pos logic applies.
a numeric vector of 0s and 1s (and NAs where present in
x). For factor and character input, the result carries a
"coding" attribute, a named integer vector documenting which
original value was mapped to 0 and which to 1.
Other data.recode:
combLevels(),
dummy(),
mReplace(),
nf(),
recodeX(),
revCode(),
stringsAsFactors()
# logical asBinary(c(TRUE, FALSE, TRUE)) # numeric (already binary) asBinary(c(0, 1, 1, 0)) # factor: second level coded as 1 by default asBinary(factor(c("control", "treatment", "control"))) # factor with explicit positive value asBinary(factor(c("control", "treatment", "control")), pos = "treatment") # character asBinary(c("no", "yes", "no", "yes")) # character with explicit positive value asBinary(c("F", "U", "F", "U"), pos = "F")# logical asBinary(c(TRUE, FALSE, TRUE)) # numeric (already binary) asBinary(c(0, 1, 1, 0)) # factor: second level coded as 1 by default asBinary(factor(c("control", "treatment", "control"))) # factor with explicit positive value asBinary(factor(c("control", "treatment", "control")), pos = "treatment") # character asBinary(c("no", "yes", "no", "yes")) # character with explicit positive value asBinary(c("F", "U", "F", "U"), pos = "F")
Translates a custom date format string using tokens like
yyyy, mm, dd, mmm, etc. into a valid
strftime-compatible format string (C-style).
asCDateFmt(fmt)asCDateFmt(fmt)
fmt |
character string. Custom date format. |
The function parses the input string sequentially and replaces
recognized tokens while leaving all other characters unchanged.
This makes it robust to compact formats (e.g. yyyymmdd)
and mixed text.
Supported tokens:
d, dd, ddd, dddd
m, mm, mmm, mmmm
y, yy, yyyy
Mapping:
yyyy -> %Y
yy, y -> %y
mm, m -> %m
mmm -> %b
mmmm -> %B
dd -> %d
d -> %e
ddd -> %a
dddd -> %A
character string. A valid strftime format.
asCDateFmt("yyyy-mm-dd") asCDateFmt("dd.mm.yy") asCDateFmt("yyyymmdd") asCDateFmt("mmm d, yyyy")asCDateFmt("yyyy-mm-dd") asCDateFmt("dd.mm.yy") asCDateFmt("yyyymmdd") asCDateFmt("mmm d, yyyy")
Checks the exported functions of an installed package, their arguments and the values of their enumerated arguments against the naming rules of the suite. Meant to run as a test in every package, so that a name which breaks a rule is found when it is introduced and not in a review.
auditNames(package, exceptions = NULL)auditNames(package, exceptions = NULL)
package |
character string, the name of an installed package. |
exceptions |
character vector of findings to accept, each written
as the |
The rules checked, with the label used in the column rule:
camelCaseexported functions and arguments are written in
lowerCamelCase. A dot is kept in S3 methods, in coercion generics
as.<Class> that really dispatch, and in argument names that are
part of the shared vocabulary (na.rm, conf.level,
sig.level, ...).
acronymonly CI, QQ, XY, ECDF, SE and AD keep
their capitals inside a name, GCD and LCM as whole names. Every
other acronym is written like a word: Rgb, Url, Html. As
arguments, FUN, R, N, S and X are capitals by
convention.
collisiona function whose name is taken by base,
stats, graphics, utils or dplyr carries the suffix X.
A name counts as taken if it exists there, or if it differs from
one only in the case of the whole word (iqr against IQR()).
An internal capital makes a name of its own: combN() is not
combn().
suffixXand no function carries it without such a collision.
dotExportno function is exported with a leading dot, the graphics helpers of the plotting framework excepted.
forwardedan argument name taken over from another package
(ignore.case, useNA, all.inside, ...) is kept only where the
value is passed on to another function.
replacednames the rules have replaced: alpha
(sig.level), seed (the caller uses set.seed()), pkg
(package), fun in an exported function (FUN), dat
(data), grp (groups), w (weights), level, color and
cols (col), obs and resp (ref), the prefix num for a
count (n), the suffix Args for a list of arguments, and g and
horizontal in plot functions (groups, horiz).
enumValuethe values of an enumerated argument are lower
case, words joined by a hyphen ("wald-cc"). Values that belong to
the function they are passed on to, such as "two.sided" or the
names in p.adjust.methods, are left alone. A value that names an
element of the result (which = "tauB" returning $tauB) follows
the rule for results instead; the audit cannot see that and
reports it, so such values are listed as exceptions.
Arguments of an S3 method that its generic defines are not checked:
print.foo(x, ...) and predict.foo(object, newdata, ...) are given
by the generic. Re-exported functions are skipped altogether.
What the audit cannot see is a word boundary that was never written:
maxlen and nlow are single lower case words to it. Such names are
found by reading, not by this function.
a data frame with one row per finding and the columns
package, fun, arg (NA for a finding on the function name),
rule, detail and key, the form in which the finding is named
in exceptions. It has no rows if the package complies. The
attribute "unused" holds the exceptions that matched no finding.
Other pkg.funinfo:
funArgs(),
funCalls(),
funKeywords(),
funList(),
rdLabels(),
rdTitle()
res <- auditNames("bedrock") res[, c("fun", "arg", "rule", "detail")] # as a test: no findings beyond the documented exceptions, and no # exception without a finding accepted <- c("isNA" = "NA is R's own constant, not an acronym") res <- auditNames("bedrock", exceptions = names(accepted)) attr(res, "unused")res <- auditNames("bedrock") res[, c("fun", "arg", "rule", "detail")] # as a test: no findings beyond the documented exceptions, and no # exception without a finding accepted <- c("isNA" = "NA is R's own constant, not an acronym") res <- auditNames("bedrock", exceptions = names(accepted)) attr(res, "unused")
The between and outside operators are used to check, whether a vector of given values x lie within a defined range (or outside respectively). The values can be numbers, text or dates. Ordered factors are supported.
x %[]% rng x %[)% rng x %(]% rng x %()% rng x %][% rng x %](% rng x %)[% rng x %)(% rngx %[]% rng x %[)% rng x %(]% rng x %()% rng x %][% rng x %](% rng x %)[% rng x %)(% rng
x |
a variable with at least ordinal scale, usually a numeric value, but can be an ordered factor or a text as well. Texts would be treated alphabetically. |
rng |
a vector of two values or a matrix with 2 columns, defining the
minimum and maximum of the range for x. |
The "BETWEEN" operators basically combine two conditional statements into
one and simplify the query process.
They are merely a wrapper for:
x >= rng[1] & x <= rng[2], where the round bracket ( means
strictly greater (>) and the square bracket [ means
greater or equal (>=). Numerical values of x will be handled by
C-code, which is significantly faster than two comparisons in R (especially
when x is huge).
For the matching outside-operator, boundary elements of the corresponding
between-range return FALSE; that is, they are not considered outside
whenever the negated between-operator includes that boundary.
Both arguments, x and rng, will be recycled to the highest
dimension, which is either the length of the vector (x) or the number
of rows of the matrix (rng).
See also the routines used to check,
whether two ranges overlap (overlapSize(),
distance()).
The "OUTSIDE" operators are the negations of the corresponding "BETWEEN" operators, matched by meaning rather than by mirrored bracket symbols:
%][% negates %()% (strictly outside both bounds)
%](% negates %(]%
%)[% negates %[)%
%)(% negates %[]% (strictly outside, both bounds
of the between-operator were closed)
a logical vector of the same length as x.
Other data.interval:
intervals,
range-operators
x <- 1:9 x %[]% c(3,5) # outside x <- 1:9 x %][% c(3,5) c(x,NA) %[]% c(3,5) x %(]% c(3,5) # no result when from > to: x %[]% c(5,3) x %(]% c(5,5) # no problem: ordered(x) %[]% c(3,5) # not meaningful: factor(x) %[]% c(3,5) # characters letters[letters %(]% c("d","h")] # select numbers between 0.4 and 0.5 x <- runif(20) x %[]% c(0.4, 0.5) # use it with an ordered factor x <- ordered(sample(LETTERS, 20), levels = LETTERS) x %[)% c("G","K") # use multiple ranges 2 %[]% cbind(1:4,2:5) # both arguments are recycled c(2,3) %[]% cbind(1:4,2:5)x <- 1:9 x %[]% c(3,5) # outside x <- 1:9 x %][% c(3,5) c(x,NA) %[]% c(3,5) x %(]% c(3,5) # no result when from > to: x %[]% c(5,3) x %(]% c(5,5) # no problem: ordered(x) %[]% c(3,5) # not meaningful: factor(x) %[]% c(3,5) # characters letters[letters %(]% c("d","h")] # select numbers between 0.4 and 0.5 x <- runif(20) x %[]% c(0.4, 0.5) # use it with an ordered factor x <- ordered(sample(LETTERS, 20), levels = LETTERS) x %[)% c("G","K") # use multiple ranges 2 %[]% cbind(1:4,2:5) # both arguments are recycled c(2,3) %[]% cbind(1:4,2:5)
Create a binary tree of a given number of nodes n. Can be used to
organize a sorted numeric vector as a binary tree.
binaryTree(n)binaryTree(n)
n |
integer, size of the tree. |
If we index the nodes of the tree as 1 for the top, 2–3 for the next horizontal row, 4–7 for the next, ... then the parent-child traversal becomes particularly easy. The basic idea is that the rows of the tree start at indices 1, 2, 4, ....
binaryTree(13) yields the vector c(8, 4, 9, 2, 10, 5, 11, 1, 12, 6, 13, 3, 7) meaning that the smallest element will be in position 8
of the tree, the next smallest in position 4, etc.
an integer vector of length n.
Substantially based on code by Terry Therneau, with major extensions and improvements by the package author.
pharos::plotBinaryTree
Other data.order:
revX(),
sortX()
binaryTree(12)binaryTree(12)
Safely constructs a file path from a directory and a filename, independent of whether the directory ends with a trailing slash. The resulting path uses forward slashes.
buildPath(dir, filename)buildPath(dir, filename)
dir |
character string. Directory path. |
filename |
character string. File name to append to |
Trailing slashes (or backslashes) in dir are removed before the
components are joined, so buildPath("data", "file.csv") and
buildPath("data/", "file.csv") yield the same result.
The path is then passed through
normalizePath()with
mustWork = FALSE, so paths that do not (yet) exist are allowed.
Note that normalizePath resolves existing paths to absolute form,
while non-existing paths are returned as constructed (i.e. possibly
relative).
Both arguments are vectorized in the usual
file.path() manner.
a character string representing the file path.
Converting between forward slashes and backslashes is a frequent
necessity – and a hassle – especially in Windows. The
cycleSlashes() function in the swissValet package is
useful for this purpose.
Other file.path:
findDownload(),
isFilePath(),
isUrl(),
splitPath(),
urlExists()
buildPath("data", "file.csv") buildPath("data/", "file.csv")buildPath("data", "file.csv") buildPath("data/", "file.csv")
Conditionally evaluate a function depending on the value of an argument. This is a convenient helper for optional features such as plotting, logging, or callbacks, where the user can enable, disable, or parameterize a function call via a single argument.
callIf(FUN, arg, defaults = NULL, forbidden = NULL, warn = TRUE)callIf(FUN, arg, defaults = NULL, forbidden = NULL, warn = TRUE)
FUN |
a function to be called. |
arg |
controls whether and how
|
defaults |
a named list of default arguments passed to |
forbidden |
optional character vector of argument names that are not
allowed. If any of these appear in |
warn |
logical. If |
This function implements a flexible pattern for optional function calls:
Enable/disable behavior with TRUE/FALSE
Customize behavior with a list of arguments
Provide safe defaults and restrict certain arguments
When merging defaults and arg, user-supplied arguments take
precedence. Unlike modifyList(), elements with the value
NULL are preserved and passed on to FUN (so that an explicit
NULL can be used to reset an argument).
returns the result of FUN(...) if called. If arg is
FALSE, NULL, or NA, returns NULL invisibly.
Other pkg.args:
extractArgs(),
getDotsArg(),
mergeArgs(),
recycle()
# Simple usage: skip callIf(message, FALSE) # Call with defaults callIf(message, TRUE, defaults = list("Hello world")) # Call with explicit arguments callIf(message, list(x = "Hello from callIf")) # With defaults + override callIf(plot, list(x = 1:5), defaults = list(y = 1:5, type = "l")) # Forbid arguments callIf(plot, list(x = 1:5, y = 1:5, col = "red"), forbidden = "col") # Typical use case: optional plotting x <- 1:10 y <- x^2 callIf(plot, TRUE, defaults = list(x, y))# Simple usage: skip callIf(message, FALSE) # Call with defaults callIf(message, TRUE, defaults = list("Hello world")) # Call with explicit arguments callIf(message, list(x = "Hello from callIf")) # With defaults + override callIf(plot, list(x = 1:5), defaults = list(y = 1:5, type = "l")) # Forbid arguments callIf(plot, list(x = 1:5, y = 1:5, col = "red"), forbidden = "col") # Typical use case: optional plotting x <- 1:10 y <- x^2 callIf(plot, TRUE, defaults = list(x, y))
A dataset representing a standard deck of playing Cards. Each row corresponds to a single card and includes information such as suit, rank and numerical value.
CardsCards
A data frame with 52 observations and X variables:
Name of the card.
Rank of the card (e.g. 2–10, Jack, Queen, King, Ace).
Suit of the card (e.g. hearts, diamonds, clubs, spades).
The dataset can be used for simulations, probability calculations and teaching examples involving discrete outcomes and combinatorics.
The dataset represents a complete deck without jokers. It is suitable for probability experiments, simulations and demonstrations of categorical data.
Simulated data.
Other datasets:
Pizza,
Roulette,
Tarot,
readCourseData()
head(Cards) table(Cards$suit)head(Cards) table(Cards$suit)
Convert characters to their numeric character codes and vice versa.
charToAscii(x, output = c("vector", "list")) asciiToChar(x)charToAscii(x, output = c("vector", "list")) asciiToChar(x)
x |
for |
output |
character string specifying the output representation.
One of |
charToAscii() converts each character in a string to its
corresponding numeric code.
asciiToChar() converts numeric codes back to characters.
Only values in the range 1:127 belong to the ASCII standard and
therefore have the same meaning across all systems. Values
128:255 depend on the current character encoding (for example
ISO-8859-1 or Windows-1252) and may produce different characters on
different platforms.
Note that 0 (NUL) cannot be represented in R character strings
and is therefore not supported.
The output argument controls the representation returned by
charToAscii():
"vector"Simplifies the result whenever possible.
Returns an integer vector if:
the input consists of a single string, or
all input strings have length one.
Otherwise, a list of integer vectors is returned.
"list"Always returns a list of integer vectors.
charToAscii() returns either an integer vector or a
list of integer vectors, depending on output.
asciiToChar() returns a character vector.
Other string.transform:
mGsub(),
strSplitToCol(),
strSplitToDummy()
# basic usage x <- charToAscii("Silvia") x asciiToChar(x) # multiple strings charToAscii(c("A", "BC"), output = "list") # split into individual characters strsplit(asciiToChar(x), split = NULL) # comparison with raw representation charToRaw("Silvia")# basic usage x <- charToAscii("Silvia") x asciiToChar(x) # multiple strings charToAscii(c("A", "BC"), output = "list") # split into individual characters strsplit(asciiToChar(x), split = NULL) # comparison with raw representation charToRaw("Silvia")
Checks that conf.level is a single number in , or
NA. Intended for the confidence-interval functions across the
suite, so that all of them accept the same values and refuse the rest
with the same message.
checkConfLevel(conf.level, allowNA = TRUE)checkConfLevel(conf.level, allowNA = TRUE)
conf.level |
the value to check. |
allowNA |
logical. |
The order of the tests is the point of this function. NA is
logical, so a check that leads with !is.numeric() rejects
the very default most of these functions carry. And is.na() on a
vector of length other than one turns the surrounding if into the
error message, which then talks about the condition instead of the
argument. Length first, then type, then range.
NaN is excluded explicitly: is.na(NaN) is TRUE, so
without that test a NaN would be silently accepted as "no
interval wanted".
conf.level, invisibly,
so the check can be used in an
assignment: conf.level <- checkConfLevel(conf.level).
checkFlag(), checkCount(), checkString()
checkConfLevel(0.95) checkConfLevel(NA) # all of these are rejected: try(checkConfLevel(c(0.9, 0.95))) # length try(checkConfLevel(NULL)) # length try(checkConfLevel(NaN)) # not a level, and not NA either try(checkConfLevel(0)) # range is open # where the interval is part of the result, NA is refused as well try(checkConfLevel(NA, allowNA = FALSE))checkConfLevel(0.95) checkConfLevel(NA) # all of these are rejected: try(checkConfLevel(c(0.9, 0.95))) # length try(checkConfLevel(NULL)) # length try(checkConfLevel(NaN)) # not a level, and not NA either try(checkConfLevel(0)) # range is open # where the interval is part of the result, NA is refused as well try(checkConfLevel(NA, allowNA = FALSE))
Checks that an argument is a single finite integer, not smaller than
min. Meant for the many size arguments in the suite - digits,
sep, width, nPerm, R and the like - which
are conceptually counts rather than numbers and were previously
spelled out by hand wherever they occur.
checkCount(x, min = 0L, name = deparse(substitute(x)))checkCount(x, min = 0L, name = deparse(substitute(x)))
x |
the value to check. |
min |
the smallest admissible value, |
name |
the argument name to use in the message. Defaults to the expression that was passed. |
A whole number stored as a double is accepted, as that is what
arithmetic on integers produces and what a user typing 2 supplies.
TRUE is not, although it would survive as.integer(): a flag
that reaches a count argument is a mistake, not a shorthand for one.
The order of the tests is the same as in checkConfLevel(), length
first, then type, then value, so that the message names the argument
rather than the condition that failed.
x, invisibly.
checkConfLevel(), checkFlag(), checkString()
sep <- 2 checkCount(sep) width <- 80 checkCount(width, min = 1) # all of these are rejected: try(checkCount(1.5)) # not a whole number try(checkCount(-1)) # below the default minimum try(checkCount(TRUE)) # a flag is not a countsep <- 2 checkCount(sep) width <- 80 checkCount(width, min = 1) # all of these are rejected: try(checkCount(1.5)) # not a whole number try(checkCount(-1)) # below the default minimum try(checkCount(TRUE)) # a flag is not a count
Checks that an argument is a single non-missing TRUE or
FALSE. Meant for the many switches in the suite -
correct, unbiased, scaled, paired and the
like - which were previously either unchecked or checked in three
different ways.
checkFlag(x, name = deparse(substitute(x)))checkFlag(x, name = deparse(substitute(x)))
x |
the value to check. |
name |
the argument name to use in the message. Defaults to the
expression that was passed, which is right in the ordinary case
|
NA is rejected on purpose. It is a logical of length one and
therefore passes is.logical(), but a flag that is neither on nor
off has no meaning for a switch - and it propagates silently, because
if (NA) is an error somewhere further down rather than here.
x, invisibly.
checkConfLevel(), checkCount(), checkString()
correct <- TRUE checkFlag(correct) correct <- NA try(checkFlag(correct)) # "'correct' must be a single ..."correct <- TRUE checkFlag(correct) correct <- NA try(checkFlag(correct)) # "'correct' must be a single ..."
Checks that an argument is a single non-missing character string.
Meant for the labelling arguments across the suite - dataName,
captions, axis titles - where a vector or an NA would otherwise
travel unnoticed into printed output.
checkString(x, name = deparse(substitute(x)))checkString(x, name = deparse(substitute(x)))
x |
the value to check. |
name |
the argument name to use in the message. Defaults to the expression that was passed. |
An optional argument that may also be NULL is guarded by the
caller, if (!is.null(dataName)) checkString(dataName), rather than
by a further argument here: whether the absence of a label is
admissible is a decision of the function, not of the check.
The empty string is accepted. It is a legitimate label, and a caller that needs a non-empty one says so itself.
x, invisibly.
checkConfLevel(), checkFlag(), checkCount()
dataName <- "smoking by sex" checkString(dataName) # all of these are rejected: try(checkString(NA_character_)) # a missing label is not a label try(checkString(c("a", "b"))) # length try(checkString(42)) # typedataName <- "smoking by sex" checkString(dataName) # all of these are rejected: try(checkString(NA_character_)) # a missing label is not a label try(checkString(c("a", "b"))) # length try(checkString(42)) # type
Find the value(s) in a vector closest to a reference value. Multiple values are returned if ties occur or if duplicate values share the same minimum distance.
closest(x, val, output = "value", na.rm = FALSE)closest(x, val, output = "value", na.rm = FALSE)
x |
a numeric vector to search in. |
val |
the reference value. May be a vector; see Details. |
output |
character string specifying the output representation.
One of |
na.rm |
logical. If |
Distance is computed as . Ties are detected via
isZero() rather than exact equality, which avoids spurious
misses due to floating-point representation (e.g.
0.3 - 0.2 != 0.1).
When na.rm = TRUE, NA elements are excluded from the
search but the original index positions of the remaining elements are
preserved, so output = "index" always refers to positions in
the original x.
When val or output are vectors, each element is
processed independently and a list is returned.
Recycling follows standard R rules.
if val and output are scalar:
numeric vector if output = "value".
integer vector if output = "index".
If val or output are vectors:
a list with one element per value of val.
Returns NA if x is empty or all-NA
(with na.rm = TRUE).
Other math.basic:
crossProd(),
crossProdN(),
dotProd(),
roundTo(),
unirootAll()
# basic set.seed(8) x <- runif(10) * 10 closest(x, 3.1) sort(x) y <- sample(10, size = 10, replace = TRUE) # multiple observations of the same closest value closest(y, val = 6) # get the relevant positions closest(y, val = 6, output = "index") # two different values having the same distance (tie) closest(c(2, 3, 4, 5), val = 3.5) # na.rm preserves original index positions closest( c(NA, 5, 8), val = 6, output = "index", na.rm = TRUE ) # 2, not 1 # vectorize "a" closest(c(2, 3, 4, 5), val = c(3.1, 3.9)) # vectorize "output" closest( c(2, 3, 4, 5), val = 3.1, output = c("value", "index") ) closest( c(2, 3, 4, 5), val = c(3.1, 3.9), output = c("value", "index") )# basic set.seed(8) x <- runif(10) * 10 closest(x, 3.1) sort(x) y <- sample(10, size = 10, replace = TRUE) # multiple observations of the same closest value closest(y, val = 6) # get the relevant positions closest(y, val = 6, output = "index") # two different values having the same distance (tie) closest(c(2, 3, 4, 5), val = 3.5) # na.rm preserves original index positions closest( c(NA, 5, 8), val = 6, output = "index", na.rm = TRUE ) # 2, not 1 # vectorize "a" closest(c(2, 3, 4, 5), val = c(3.1, 3.9)) # vectorize "output" closest( c(2, 3, 4, 5), val = 3.1, output = c("value", "index") ) closest( c(2, 3, 4, 5), val = c(3.1, 3.9), output = c("value", "index") )
If several vectors are supplied, the evaluation will be elementwise, resp.
rowwise if x is a data.frame or a matrix. The first element of the result is
the first non NA element of the first elements of all the arguments,
the second element of the result is the one of the second elements of all
the arguments and so on.
Shorter inputs (of non-zero length) are NOT
recycled: if all inputs have length greater than 1, they must have the same
length (the function will bark otherwise). If any input has length 1 or 0,
all inputs are flattened into a single vector (dropping NULLs) and
the first valid element is returned, in the manner of a scalar SQL
COALESCE.
The idea is borrowed from SQL. Might sometimes be useful
when preparing data in R instead of in SQL.
coalesceX(..., method = c("is.na", "is.null", "is.finite"), flatten = TRUE)coalesceX(..., method = c("is.na", "is.null", "is.finite"), flatten = TRUE)
... |
the elements to be evaluated. This can either be a single vector, several vectors of same length, a matrix, a data.frame or a list of vectors (of same length). See examples. |
method |
one out of |
flatten |
logical, defines whether lists are going to be flattened
(default |
return a single vector of the first non NA element(s) of the
given data structure.
Other vector.na:
isNA(),
locf(),
naIf(),
naReplace()
coalesceX(c(NA, NA, NA, 5, 3)) coalesceX(c(NA, NULL, "a")) coalesceX(NULL, 5, 3) d.frm <- data.frame(matrix(c( 1, 2, NA, 4, NA, NA, 3, 1, NaN, 2, 3, 1, NA, Inf, 1, 1), nrow=4, byrow=TRUE) ) coalesceX(d.frm) coalesceX(as.matrix(d.frm)) coalesceX(d.frm$X1, d.frm$X2, d.frm$X3, d.frm$X4) coalesceX(d.frm$X1, d.frm$X2, d.frm$X3, d.frm$X4, method="is.finite") coalesceX(list(d.frm[,1], d.frm[,2])) # returns the first finite element (skips NA, Inf, NaN) coalesceX(d.frm, method="is.finite") # returns the first argument that is not NULL coalesceX(NULL, NULL, 7, method = "is.null") # with characters (take care, factors won't work!) # is.finite does not make sense here... d.frm <- data.frame(matrix(c( "a", "b", NA, "4", NA, NA, "g", "m", NA_character_,"hfdg", "rr", "m", NA, Inf, 1, 1), nrow=4, byrow=TRUE) , stringsAsFactors = FALSE) coalesceX(d.frm$X1, d.frm$X2, d.frm$X3, d.frm$X4) coalesceX(d.frm) coalesceX(as.list(d.frm))coalesceX(c(NA, NA, NA, 5, 3)) coalesceX(c(NA, NULL, "a")) coalesceX(NULL, 5, 3) d.frm <- data.frame(matrix(c( 1, 2, NA, 4, NA, NA, 3, 1, NaN, 2, 3, 1, NA, Inf, 1, 1), nrow=4, byrow=TRUE) ) coalesceX(d.frm) coalesceX(as.matrix(d.frm)) coalesceX(d.frm$X1, d.frm$X2, d.frm$X3, d.frm$X4) coalesceX(d.frm$X1, d.frm$X2, d.frm$X3, d.frm$X4, method="is.finite") coalesceX(list(d.frm[,1], d.frm[,2])) # returns the first finite element (skips NA, Inf, NaN) coalesceX(d.frm, method="is.finite") # returns the first argument that is not NULL coalesceX(NULL, NULL, 7, method = "is.null") # with characters (take care, factors won't work!) # is.finite does not make sense here... d.frm <- data.frame(matrix(c( "a", "b", NA, "4", NA, NA, "g", "m", NA_character_,"hfdg", "rr", "m", NA, Inf, 1, 1), nrow=4, byrow=TRUE) , stringsAsFactors = FALSE) coalesceX(d.frm$X1, d.frm$X2, d.frm$X3, d.frm$X4) coalesceX(d.frm) coalesceX(as.list(d.frm))
Aggregates a table or ftable object by reassigning the levels
of one or more dimensions according to user-supplied mappings, and summing
the frequencies within each resulting level combination.
collapseTable(x, ..., strict = TRUE)collapseTable(x, ..., strict = TRUE)
x |
a |
... |
named or unnamed mapping vectors specifying how levels of each dimension should be collapsed. Each mapping vector must have length equal to the number of levels in the corresponding dimension. |
strict |
logical (default |
Mapping vectors define how factor levels are reassigned. Element i
specifies the new label for the i-th original level. Repeated values
in a mapping vector cause the corresponding levels to be merged.
Argument matching
Named arguments are matched to dimensions by name
(e.g., age = c("young", "adult")).
Unnamed arguments are assigned to dimensions in order.
Mixed usage assigns named arguments first, then remaining unnamed arguments in order.
Constraints
Each dimension may be specified at most once.
Mapping vectors must have the same length as the number of levels of the corresponding dimension.
NA values in mapping vectors are not allowed.
Level ordering The order of the resulting levels follows the first occurrence of each value in the mapping vector.
Error handling
If strict = TRUE, unknown dimension names result in an error,
and positional assignment of unnamed arguments produces a warning.
If strict = FALSE, unknown dimensions produce a warning
(and are ignored), and positional assignment is silent.
a collapsed table object with updated dimensions and
aggregated frequencies.
Other data.reshape:
long-wide-reshape,
splitAt(),
splitX(),
untable()
tab <- xtabs(~ gear + cyl, data = mtcars) tab # merge the 4- and 6-cylinder categories collapseTable(tab, cyl = c("le6", "le6", "8")) # positional assignment (first dimension), silent with strict = FALSE collapseTable(tab, c("3-4", "3-4", "5"), strict = FALSE)tab <- xtabs(~ gear + cyl, data = mtcars) tab # merge the 4- and 6-cylinder categories collapseTable(tab, cyl = c("le6", "le6", "8")) # positional assignment (first dimension), silent with strict = FALSE collapseTable(tab, c("3-4", "3-4", "5"), strict = FALSE)
Wraps text in a character matrix so that it's displayed over more than one line.
columnWrap(x, width = NULL)columnWrap(x, width = NULL)
x |
a character vector, typically one row of a matrix
(e.g. via |
width |
integer, the width of the columns in characters, recycled to
the length of |
A data.frame containing character columns with long texts is often wrapped
by columns. This can lead to a loss of overview. columnWrap() wraps the
lines within the columns.
a character matrix with one column per element of x and
one row per wrapped line.
Other data.print:
printCharMatrix()
print(columnWrap("This is a very long text for a table", 12))print(columnWrap("This is a very long text for a table", 12))
Extracts and combines the levels from one or more vectors or factors. Non-factor inputs are coerced to factors before extracting levels.
combLevels(..., sorted = FALSE, na = FALSE)combLevels(..., sorted = FALSE, na = FALSE)
... |
one or more vectors or factors. |
sorted |
logical; if |
na |
logical; if |
Each input is coerced to a factor (if not already one), and its levels are extracted. The union of all levels is returned. Unused levels of factor inputs are preserved.
By default, missing values (NA) are not included as a level.
Set na = TRUE to include them; NA is then placed last
when sorting.
The order of levels follows their first occurrence unless
sorted = TRUE.
a character vector containing the unique levels across all inputs.
Other data.recode:
asBinary(),
dummy(),
mReplace(),
nf(),
recodeX(),
revCode(),
stringsAsFactors()
x <- factor(c("A", "B")) y <- c("B", "C") combLevels(x, y) # Sorted levels combLevels(x, y, sorted = TRUE) # Including NA as a level x <- c("A", NA) y <- c("B", NA) combLevels(x, y, na = TRUE)x <- factor(c("A", "B")) y <- c("B", "C") combLevels(x, y) # Sorted levels combLevels(x, y, sorted = TRUE) # Including NA as a level x <- c("A", NA) y <- c("B", NA) combLevels(x, y, na = TRUE)
Return the number of combinations with and without replacement and order.
combN(n, m, replace = FALSE, ordered = FALSE)combN(n, m, replace = FALSE, ordered = FALSE)
n |
number of elements from which to choose. |
m |
number of elements to choose. For |
replace |
logical; whether repetition of the same element is allowed.
Defaults to |
ordered |
logical. Does the order matter? Default is |
a numeric value.
combn(), choose(), factorial(),
vignette("Combinatorics", package = "bedrock")
Other combinatorics:
combPairs(),
combSet(),
pairApply(),
permn(),
randGroupSplit(),
sampleX()
n <- 5; m <- 2 combN(n, m, replace=TRUE, ordered=FALSE) combN(n, m, replace=TRUE, ordered=TRUE) combN(n, m, replace=FALSE, ordered=TRUE) combN(n, m, replace=FALSE, ordered=FALSE)n <- 5; m <- 2 combN(n, m, replace=TRUE, ordered=FALSE) combN(n, m, replace=TRUE, ordered=TRUE) combN(n, m, replace=FALSE, ordered=TRUE) combN(n, m, replace=FALSE, ordered=FALSE)
Returns all combinations of 2 out of the elements in x or x and y (if
defined). Combinations of the same elements will be dropped (no replacing).
The vector x need not contain unique values. Duplicate elements
in x will result in duplicate pairs.
combPairs(x, y = NULL)combPairs(x, y = NULL)
x |
a vector of elements, must contain at least 2 elements if
|
y |
a vector of elements, need not be same dimension as x. If y is not
|
If y = NULL then all combination of 2 out of x are returned.
If y
is defined then all combinations of x and y are calculated.
a data.frame with two columns X1 and X2
containing the pairwise combinations.
combn(), expand.grid(), outer(), lower.tri()
Other combinatorics:
combN(),
combSet(),
pairApply(),
permn(),
randGroupSplit(),
sampleX()
combPairs(letters[1:4]) combPairs(x = letters[1:4], y = LETTERS[1:2]) # get all pairs of combinations between factors and numerics out of a data.frame combPairs(which(sapply(CO2, is.numeric)), which(sapply(CO2, is.factor)))combPairs(letters[1:4]) combPairs(x = letters[1:4], y = LETTERS[1:2]) # get all pairs of combinations between factors and numerics out of a data.frame combPairs(which(sapply(CO2, is.numeric)), which(sapply(CO2, is.factor)))
Return the value sets of combinations.
combSet(x, m, replace = FALSE, ordered = FALSE, output = c("matrix", "list"))combSet(x, m, replace = FALSE, ordered = FALSE, output = c("matrix", "list"))
x |
a vector of numeric values or characters. Character values need not be unique. |
m |
number of elements to choose. May be a vector. |
replace |
logical. Should repetition of the same element
be allowed? Default is |
ordered |
logical; whether order matters.
Default is |
output |
character string specifying the output representation.
One of |
Depending on output, the result is returned either as:
a matrix with one combination per row
a flat list where each element represents one combination
If m contains more than one value, combinations are generated
independently for each value of m.
if output = "matrix":
a matrix with one combination per row.
if length(m) > 1, a list of matrices.
If output = "list":
a flat list with one element per combination.
combn(), choose(), factorial(),
vignette("Combinatorics")
Other combinatorics:
combN(),
combPairs(),
pairApply(),
permn(),
randGroupSplit(),
sampleX()
x <- letters[1:4] m <- 2 # combinations with replacement combSet(x, m, replace = TRUE, ordered = FALSE) # ordered combinations with replacement combSet(x, m, replace = TRUE, ordered = TRUE) # ordered combinations without replacement combSet(x, m, replace = FALSE, ordered = TRUE) # unordered combinations without replacement combSet(x, m, replace = FALSE, ordered = FALSE) # return as flat list x <- letters[1:5] combSet( x = x, m = c(1, 3, 5), output = "list" )x <- letters[1:4] m <- 2 # combinations with replacement combSet(x, m, replace = TRUE, ordered = FALSE) # ordered combinations with replacement combSet(x, m, replace = TRUE, ordered = TRUE) # ordered combinations without replacement combSet(x, m, replace = FALSE, ordered = TRUE) # unordered combinations without replacement combSet(x, m, replace = FALSE, ordered = FALSE) # return as flat list x <- letters[1:5] combSet( x = x, m = c(1, 3, 5), output = "list" )
Compares two data frames row-by-row based on a key column, identifying rows present in only one of the two frames and columns that differ in matched rows.
compareDataFrames(x, y, key)compareDataFrames(x, y, key)
x |
a data frame. |
y |
a data frame to compare against |
key |
character string. Name of the column used as row identifier.
Must be present in both |
Only columns present in both data frames are compared. Rows are matched by
the key column using identical() for element-wise comparison,
so type differences (e.g., integer vs. double) will be flagged
as differences.
The values of the key column must be unique in both data frames.
a named list with four elements:
identicallogical. TRUE if the two data frames are
identical with respect to the common columns and key.
onlyInXdata frame of rows whose key value appears in
x but not in y.
onlyInYdata frame of rows whose key value appears in
y but not in x.
diffsdata frame with columns named after the key
argument (the key value) and diffCols (a list column of character
vectors naming the differing columns for that key).
Other data.equal:
allDuplicated(),
allIdentical()
x <- data.frame(id = c("A", "B", "C"), v1 = 1:3, v2 = c(10, 20, 30)) y <- data.frame(id = c("A", "B", "D"), v1 = c(1L, 9L, 4L), v2 = c(10, 20, 40)) compareDataFrames(x, y, key = "id")x <- data.frame(id = c("A", "B", "C"), v1 = 1:3, v2 = c(10, 20, 30)) y <- data.frame(id = c("A", "B", "D"), v1 = c(1L, 9L, 4L), v2 = c(10, 20, 40)) compareDataFrames(x, y, key = "id")
This function checks each element of a data frame or list-like object
for missing values (NA) and identifies those that are completely
observed, i.e., contain no missing entries.
completeColumns(x, output = c("names", "logical"))completeColumns(x, output = c("names", "logical"))
x |
a data.frame or list-like object whose elements are checked for missing values. |
output |
character string specifying the output representation.
One of |
An element is considered complete if it contains zero missing
values. Internally, the function uses anyNA() to detect
missing values.
if output = "names", a character vector with the names of all
complete elements.
If output = "logical", a logical vector of length
length(x), where TRUE indicates that the corresponding
element contains no missing values.
anyNA(), is.na(),
na.omit(), complete.cases()
Other data.missing:
countCompCases()
# Names of columns without missing values completeColumns(airquality) # Logical vector indicating completeness completeColumns(airquality, output = "logical")# Names of columns without missing values completeColumns(airquality) # Logical vector indicating completeness completeColumns(airquality, output = "logical")
Helper functions to inspect and analyse the use of
\\concept tags within a package.
getConcepts(package, prefix = NULL) conceptMap(package) conceptAudit(package)getConcepts(package, prefix = NULL) conceptMap(package) conceptAudit(package)
package |
character string. Name of the installed package. |
prefix |
optional character string. If given, |
These utilities extract concept metadata from Rd files and allow structured auditing of conceptual organisation inside a package.
Functions
getConcepts() - Returns all unique concepts used in a package.
conceptMap() - Returns a mapping of concepts to functions.
conceptAudit() - Returns a summary table of concept usage.
The functions use tools::Rd_db() to parse Rd files and
extract \\concept tags programmatically.
These tools are intended for package development, documentation consistency checks, and conceptual audits.
getConceptscharacter vector of unique concept names, sorted
conceptMapnamed list mapping concepts to topics
conceptAuditdata frame with the columns concept
and nTopics, ordered by decreasing frequency
getConcepts("stats") getConcepts("stats", prefix = "erf") head(conceptMap("stats")) head(conceptAudit("stats"))getConcepts("stats") getConcepts("stats", prefix = "erf") head(conceptMap("stats")) head(conceptAudit("stats"))
Return for each variable of a data frame the number of missing values and the complete cases to be expected if this variable would be omitted.
countCompCases(x)countCompCases(x)
x |
a data.frame containing the data. |
a list with three elements. The first gives the number of rows, the
second the number of complete cases for the whole data frame. The third
element tab contains the data for the single variables.
pharos::plotMiss,
complete.cases(), is.na(), na.omit()
Other data.missing:
completeColumns()
countCompCases(airquality)countCompCases(airquality)
Computes the cross product in three-dimensional space for vectors or matrices. For matrices, the operation can be applied row-wise or column-wise.
crossProd(x, y, orientation = c("rows", "cols"))crossProd(x, y, orientation = c("rows", "cols"))
x |
a numeric or complex vector of length 3, or a matrix with one dimension of length 3. |
y |
a numeric or complex vector or matrix with the same dimensions as |
orientation |
character string specifying whether vectors are stored in rows or columns
when matrices are supplied. Must be one of |
For vectors and , the cross product is:
For matrix inputs:
orientation = "rows": each row is treated as a vector (requires ncol(x) == 3)
orientation = "cols": each column is treated as a vector (requires nrow(x) == 3)
Numeric and complex inputs can be mixed; standard R coercion rules apply.
a vector of length 3 if inputs are vectors.
a matrix if matrices are supplied. Dimension names along the
vector axis are propagated from x, the component axis is
labelled x, y, z.
Other math.basic:
closest(),
crossProdN(),
dotProd(),
roundTo(),
unirootAll()
# Vector case crossProd(c(1,0,0), c(0,1,0)) # Row-wise x <- matrix(c(1,0,0, 0,1,0), ncol = 3, byrow = TRUE) y <- matrix(c(0,1,0, 0,0,1), ncol = 3, byrow = TRUE) crossProd(x, y, "rows") # Column-wise x <- matrix(1:9, nrow = 3) y <- matrix(9:1, nrow = 3) crossProd(x, y, "cols")# Vector case crossProd(c(1,0,0), c(0,1,0)) # Row-wise x <- matrix(c(1,0,0, 0,1,0), ncol = 3, byrow = TRUE) y <- matrix(c(0,1,0, 0,0,1), ncol = 3, byrow = TRUE) crossProd(x, y, "rows") # Column-wise x <- matrix(1:9, nrow = 3) y <- matrix(9:1, nrow = 3) crossProd(x, y, "cols")
Computes a vector orthogonal to all rows of a matrix using a determinant-based construction. This generalizes the cross product to higher dimensions.
crossProdN(x)crossProdN(x)
x |
a numeric or complex vector of length 2, or a matrix of dimension
|
For a matrix with dimensions , the result is a vector
in orthogonal to all rows of . The components are
given by:
where is the matrix obtained by removing the -th column.
For a vector of length 2, the function returns the perpendicular vector
, consistent with the formula above.
Internally, the function computes a nullspace vector using SVD (which is
numerically stable also for ill-conditioned input) and rescales it to match
the magnitude of the determinant-based generalized cross product. For
numeric input, the sign is chosen to reproduce the orientation of the
determinant formula (and hence
anticommutativity: swapping two rows of flips the sign of the
result). For complex input, where det() is not available, the sign
is fixed by the convention that the first component with non-zero modulus
has a positive real part.
a numeric or complex vector of length .
Other math.basic:
closest(),
crossProd(),
dotProd(),
roundTo(),
unirootAll()
# 2D case crossProdN(c(1, 2)) # 3D case (standard cross product) A <- matrix(c(1,0,0, 0,1,0), nrow = 2, byrow = TRUE) crossProdN(A) # swapping rows flips the sign (anticommutativity) crossProdN(A[2:1, ])# 2D case crossProdN(c(1, 2)) # 3D case (standard cross product) A <- matrix(c(1,0,0, 0,1,0), nrow = 2, byrow = TRUE) crossProdN(A) # swapping rows flips the sign (anticommutativity) crossProdN(A[2:1, ])
Reads a documentation sheet from an Excel file and extracts variable descriptions and coding information.
dataDescription(file, sheet = "Description")dataDescription(file, sheet = "Description")
file |
character string. Path to the Excel file. |
sheet |
character string. Name of the documentation sheet.
Default is |
The function reads the specified sheet and trims trailing empty rows.
If a column named "Codes" is present, its contents are split by
line breaks and returned as a list of codes per variable, keyed by the
"Variable" column.
The Excel sheet is expected to contain at least:
Variable names
Descriptions
Optional coding definitions
If the sheet does not exist or no additional sheets are present,
the function returns NULL.
a list with the following components:
desctable: A data frame containing the description table.
codes: A named list of code definitions per variable.
Other label.import:
openDataObject()
fn <- system.file("extdata", "example.xlsx", package = "bedrock") desc <- dataDescription(fn) desc$desctable desc$codes[["gender"]]fn <- system.file("extdata", "example.xlsx", package = "bedrock") desc <- dataDescription(fn) desc$desctable desc$codes[["gender"]]
Computes the sum of digits for whole-numbered inputs. Negative values are handled by taking the absolute value.
digitSum(x)digitSum(x)
x |
an integer vector, or a numeric vector of whole numbers. |
The function accepts integer vectors as well as doubles holding whole
numbers (e.g. 124 and 124L are both valid). Fractional
values raise an error. Missing values (NA) are propagated.
an integer vector containing the digit sums.
Other number.theory:
GCD-LCM,
divisors(),
factorize(),
fibonacci(),
isOdd(),
isPrime(),
primes()
digitSum(124) digitSum(c(10L, 99L, -1234L))digitSum(124) digitSum(c(10L, 99L, -1234L))
Calculate the proper divisors of positive natural numbers.
divisors(x)divisors(x)
x |
vector of positive whole numbers for which the divisors are to be returned. |
Divisibility is a mathematical relationship between two integers. An integer
is divisible by another integer if there is no remainder in the division.
This function returns the proper divisors of x, i.e. all
positive divisors excluding x itself. The number 11 is prime and has
only the proper divisor 1, whereas the number 12 has the proper divisors
1, 2, 3, 4 and 6. In elementary number theory, the concept of divisibility
is limited to natural numbers. The number of proper divisors can be
determined with the function length().
an integer vector containing the proper divisors in ascending
order if x is a single number, otherwise a named list of such
vectors. A prime number yields 1, and 1 itself yields
integer(0) - its only divisor is 1, which is x itself and
therefore not a proper one.
Other number.theory:
GCD-LCM,
digitSum(),
factorize(),
fibonacci(),
isOdd(),
isPrime(),
primes()
divisors(786) divisors(c(145, 786)) # the number of proper divisors length(divisors(786)) # a prime has only one, and this one is at the integer limit divisors(.Machine$integer.max)divisors(786) divisors(c(145, 786)) # the number of proper divisors length(divisors(786)) # a prime has only one, and this one is at the integer limit divisors(.Machine$integer.max)
Computes the dot product between two numeric or complex vectors, or the column-wise dot products of two matrices with identical dimensions.
dotProd(x, y)dotProd(x, y)
x |
a numeric or complex vector, or a numeric/complex matrix. |
y |
a numeric or complex vector, or a numeric/complex matrix with the
same dimensions as |
For vectors and , the dot product is defined as:
where denotes the complex conjugate of
(for real input this is simply ).
For matrices, the dot product of each column of x with the
corresponding column of y is returned.
Note that crossprod() does not conjugate its
first argument for complex input, so it computes rather
than the Hermitian inner product; this function does conjugate.
a scalar if x and y are vectors.
a numeric or complex vector containing the column-wise dot products if matrices are supplied.
Other math.basic:
closest(),
crossProd(),
crossProdN(),
roundTo(),
unirootAll()
# Vector dot product dotProd(c(1, 2, 3), c(4, 5, 6)) # Complex vectors (Hermitian inner product) dotProd(c(1+1i, 2), c(3, 4-1i)) # Matrix (column-wise dot products) x <- matrix(1:6, ncol = 2) y <- matrix(6:1, ncol = 2) dotProd(x, y)# Vector dot product dotProd(c(1, 2, 3), c(4, 5, 6)) # Complex vectors (Hermitian inner product) dotProd(c(1+1i, 2), c(3, 4-1i)) # Matrix (column-wise dot products) x <- matrix(1:6, ncol = 2) y <- matrix(6:1, ncol = 2) dotProd(x, y)
Generate a matrix of dummy codes, also known as class indicators, for a factor or class vector.
dummy( x, method = c("treatment", "sum", "helmert", "poly", "full"), base = 1, levels = NULL )dummy( x, method = c("treatment", "sum", "helmert", "poly", "full"), base = 1, levels = NULL )
x |
factor or vector of classes. |
method |
character string specifying the contrast method. One of
|
base |
integer or character string specifying the baseline group.
Only used for |
levels |
optional character vector specifying the possible levels of
|
The argument method controls the contrast coding. The option "full"
returns one indicator column for each level of x. This full-rank coding is
usually redundant for lm() and related modelling functions.
The base argument is only used by method = "treatment". The other
contrast types have no freely choosable baseline: "sum" implicitly uses
the last level as reference, "helmert" contrasts each level against the
preceding ones, and "poly" uses orthogonal polynomials.
Column names reflect the semantics of the coding: level names for
"treatment" (without the baseline), "full" (all levels), "sum"
(without the last level) and "helmert" (without the first level);
"poly" keeps the standard degree labels (.L, .Q, ...).
a matrix with dummy codes. The number of rows equals length(x).
For method = "full", the number of columns equals the number of levels.
Otherwise, the number of columns equals the number of levels minus one.
The returned matrix has an attribute "base" containing the baseline level
for treatment coding, and NA otherwise.
model.frame(), contrasts(), contr.treatment(),
contr.sum(), contr.helmert(), contr.poly()
Other data.recode:
asBinary(),
combLevels(),
mReplace(),
nf(),
recodeX(),
revCode(),
stringsAsFactors()
x <- c("red", "blue", "green", "blue", "green", "red", "red", "blue") dummy(x) dummy(x, base = 2) dummy(x, method = "sum") y <- c("Max", "Max", "Max", "Max", "Max", "Bill", "Bill", "Bill") dummy(y) dummy(y, base = "Max") dummy(y, base = "Max", method = "full") # Revert full dummy coding m <- dummy(y, method = "full") apply(m, 1, function(z) colnames(m)[z == 1]) # Revert treatment dummy coding m <- dummy(y) apply( m, 1, function(z) ifelse(sum(z) == 0, attr(m, "base"), colnames(m)[z == 1]) )x <- c("red", "blue", "green", "blue", "green", "red", "red", "blue") dummy(x) dummy(x, base = 2) dummy(x, method = "sum") y <- c("Max", "Max", "Max", "Max", "Max", "Bill", "Bill", "Bill") dummy(y) dummy(y, base = "Max") dummy(y, base = "Max", method = "full") # Revert full dummy coding m <- dummy(y, method = "full") apply(m, 1, function(z) colnames(m)[z == 1]) # Revert treatment dummy coding m <- dummy(y) apply( m, 1, function(z) ifelse(sum(z) == 0, attr(m, "base"), colnames(m)[z == 1]) )
Utility to extract a subset of arguments from a list (typically
list(...)) and merge them with default values. Elements of
dots override entries in defaults of the same name;
explicit NULL values are preserved.
extractArgs(dots, defaults, validate = NULL, returnRest = FALSE)extractArgs(dots, defaults, validate = NULL, returnRest = FALSE)
dots |
named list of arguments (usually |
defaults |
named list of default values. |
validate |
optional validation function, called with the merged argument list for its side effect. It should throw an error on invalid input; its return value is ignored. |
returnRest |
logical; if |
named list of extracted arguments, or a list with components
args and rest if returnRest = TRUE.
Other pkg.args:
callIf(),
getDotsArg(),
mergeArgs(),
recycle()
dots <- list(col = "red", lwd = 2, 99) extractArgs(dots, defaults = list(col = "black", lty = 1)) extractArgs(dots, defaults = list(col = "black", lty = 1), returnRest = TRUE)dots <- list(col = "red", lwd = 2, 99) extractArgs(dots, defaults = list(col = "black", lty = 1)) extractArgs(dots, defaults = list(col = "black", lty = 1), returnRest = TRUE)
Compute the prime factorization(s) of integer(s) x, using
Pollard's rho algorithm with deterministic Miller-Rabin primality
testing (64-bit, implemented in C++).
factorize(x)factorize(x)
x |
vector of positive whole numbers to factorize, not exceeding
|
x must not exceed 2^53 (9007199254740992), the
largest integer up to which every integer can be represented exactly.
Larger integers can still be representable – every power of two is –
but not all of them are, and above this bound x may already have
been rounded by R before it reaches this function, so a factorization
could silently be correct for a different number than the one entered – for such inputs, use the gmp package's
gmp::factorize(), which represents arbitrarily large integers
exactly (e.g. via gmp::as.bigz() or a string).
a named list() of the same length as x, each
element a 2-column matrix with column "p" the prime factors in
increasing order and column "m" their respective exponents (or
multiplicities), i.e., for a prime number x, the resulting matrix
is cbind(p = x, m = 1).
Each prime appears in exactly one row, so prod(p^m) returns
x and p is strictly increasing. x = 1 yields a
matrix with zero rows: 1 is the empty product, and
prod(numeric(0)) is 1 accordingly.
Other number.theory:
GCD-LCM,
digitSum(),
divisors(),
fibonacci(),
isOdd(),
isPrime(),
primes()
factorize(47) factorize(seq(101, 120, by=2)) # the defining invariant f <- factorize(360)[[1]] f prod(f[, "p"]^f[, "m"])factorize(47) factorize(seq(101, 120, by=2)) # the defining invariant f <- factorize(360)[[1]] f prod(f[, "p"]^f[, "m"])
Generate Fibonacci numbers. The Fibonacci numbers can also be calculated
using the golden ratio phi, as demonstrated in the examples.
fibonacci(n)fibonacci(n)
n |
nonnegative integer (<= 78) or vector of such integers. |
Generates the n-th Fibonacci number, whereas fibonacci(0) = 0.
The golden ratio is defined as phi = 0.5*(1+sqrt(5)).
Values of n are limited to 78, as larger Fibonacci numbers exceed
the range in which doubles represent integers exactly (2^53).
an integer-valued numeric vector.
https://en.wikipedia.org/wiki/Fibonacci_number
https://mathworld.wolfram.com/GoldenRatio.html
Other number.theory:
GCD-LCM,
digitSum(),
divisors(),
factorize(),
isOdd(),
isPrime(),
primes()
fibonacci(0) # 0 fibonacci(2) # 1 fibonacci(0:3) # 0 1 1 2 fibonacci(0:25) # ... 75025 121393 # Golden ratio = Fib(25)/ Fib(24) f25 <- quot(fibonacci(24:25)) # 1.618033989 phi <- (sqrt(5) + 1)/2 abs(f25 - phi) # 7.945178e-11 # Fibonacci numbers without iteration fibo <- function(n) { phi <- (sqrt(5) + 1)/2 fib <- (phi^(n+1) - (1-phi)^(n+1)) / (2*phi - 1) round(fib) } fibo(30:33) # 1346269 2178309 3524578 5702887fibonacci(0) # 0 fibonacci(2) # 1 fibonacci(0:3) # 0 1 1 2 fibonacci(0:25) # ... 75025 121393 # Golden ratio = Fib(25)/ Fib(24) f25 <- quot(fibonacci(24:25)) # 1.618033989 phi <- (sqrt(5) + 1)/2 abs(f25 - phi) # 7.945178e-11 # Fibonacci numbers without iteration fibo <- function(n) { phi <- (sqrt(5) + 1)/2 fib <- (phi^(n+1) - (1-phi)^(n+1)) / (2*phi - 1) round(fib) } fibo(30:33) # 1346269 2178309 3524578 5702887
Returns the full path to a file located in the user's Downloads directory.
findDownload(file)findDownload(file)
file |
character string. Name of the file. |
The function resolves the path to the user's Downloads directory using
an internal helper and appends file. It does not perform any
downloading; it only locates files that already exist locally.
If the file does not exist, an error is thrown.
a character string giving the full path to the file.
Other file.path:
buildPath(),
isFilePath(),
isUrl(),
splitPath(),
urlExists()
## Not run: # cannot be run automatically: reads the personal Downloads # directory of the user, where no such file exists findDownload("data.csv") ## End(Not run)## Not run: # cannot be run automatically: reads the personal Downloads # directory of the user, where no such file exists findDownload("data.csv") ## End(Not run)
Identify and extract dichotomous (binary) variables from a data frame
or matrix using isDichotomous().
flags( x, strict = FALSE, na.rm = FALSE, output = c("data", "names", "index", "logical") )flags( x, strict = FALSE, na.rm = FALSE, output = c("data", "names", "index", "logical") )
x |
a data frame or matrix. |
strict |
logical. If |
na.rm |
logical. Should missing values be ignored when checking
for dichotomous variables? Default is |
output |
character string specifying the output representation.
One of |
Variables with only missing values are not considered dichotomous
when na.rm = FALSE.
When na.rm = TRUE, such variables are treated as empty vectors
and are considered dichotomous only if strict = FALSE.
Internally, variables with indeterminate dichotomous status
(i.e. NA returned by isDichotomous())
are treated as non-dichotomous for filtering purposes.
depending on output:
"data": data frame or matrix.
"names": character vector.
"index": integer vector.
"logical": logical vector.
Other data.predicate:
isDichotomous(),
isEuclid(),
isLowCardinality(),
isNumeric(),
isWholeLike(),
isZero(),
nUnique()
dat <- data.frame( a = c(0, 1, 1, 0), b = c(1, 2, 3, 4), c = c(TRUE, FALSE, TRUE, TRUE), d = c(NA, NA, NA, NA) ) flags(dat) # effect of na.rm flags(dat, na.rm = TRUE) # return variable names flags(dat, output = "names") # return column indices flags(dat, output = "index")dat <- data.frame( a = c(0, 1, 1, 0), b = c(1, 2, 3, 4), c = c(TRUE, FALSE, TRUE, TRUE), d = c(NA, NA, NA, NA) ) flags(dat) # effect of na.rm flags(dat, na.rm = TRUE) # return variable names flags(dat, output = "names") # return column indices flags(dat, output = "index")
Returns the formal arguments of a function together with their default values.
funArgs( fun, package = NULL, sorted = FALSE, output = c("data.frame", "list", "string") )funArgs( fun, package = NULL, sorted = FALSE, output = c("data.frame", "list", "string") )
fun |
function object or function name. |
package |
optional package name used to resolve |
sorted |
logical; should arguments be sorted alphabetically?
|
output |
character string specifying the output format:
|
depending on output:
"data.frame": a data frame with columns
name and value.
"list": a named list of formal arguments.
"string": a character vector of length one.
Other pkg.funinfo:
auditNames(),
funCalls(),
funKeywords(),
funList(),
rdLabels(),
rdTitle()
funArgs("combN") funArgs("combN", output = "list") funArgs("combN", output = "string") cat(funArgs("combN", output = "string"))funArgs("combN") funArgs("combN", output = "list") funArgs("combN", output = "string") cat(funArgs("combN", output = "string"))
For screening purposes it can be useful to get a list of all function calls
our function may depend on. funCalls() parses the function
source and returns all found function calls grouped by their package.
funCalls(fun, package = NULL, sorted = FALSE)funCalls(fun, package = NULL, sorted = FALSE)
fun |
the name of the function. |
package |
optional name of a package; if given, the result is
filtered to source environments matching |
sorted |
logical; whether calls are sorted alphabetically. Defaults to
|
The source packages are resolved via find(), which only
sees attached packages. Calls to functions from packages that are not on
the search path are reported under "<not found>".
a list of character vectors with the function calls, grouped by the environment the called functions were found in.
Based on code by Nicholas Cooper, adapted to conform to package standards.
Other pkg.funinfo:
auditNames(),
funArgs(),
funKeywords(),
funList(),
rdLabels(),
rdTitle()
funCalls("combN", package="bedrock")funCalls("combN", package="bedrock")
List the keywords for specific R man pages or return a list of valid R keywords.
funKeywords(topic)funKeywords(topic)
topic |
optional, object or man page topic. |
If topic is provided, return a list of the Keywords associated with
topic. Otherwise, display the list of valid R Keywords from the R
doc/Keywords file.
if topic is missing, the R keywords documentation file is
opened for display via file.show(), invisibly
returning NULL. Otherwise, a character vector of topic names
whose keywords match topic.
Substantially based on the keywords() function from the
gtools package by Gregory R. Warnes, with minor adaptations by the
package author.
Other pkg.funinfo:
auditNames(),
funArgs(),
funCalls(),
funList(),
rdLabels(),
rdTitle()
## Show all valid R Keywords funKeywords() ## Show Keywords associated with the 'merge' function funKeywords(merge) funKeywords("merge")## Show all valid R Keywords funKeywords() ## Show Keywords associated with the 'merge' function funKeywords(merge) funKeywords("merge")
List all the functions in a package.
funList(package, exported = TRUE)funList(package, exported = TRUE)
package |
the name of the package. |
exported |
logical; whether only exported functions are listed.
Defaults to |
This is just a wrapper for the namespace inspection functions (as I always
forgot how to do the trick). By default only the exported functions are
returned; with exported = FALSE all functions defined in the
package namespace are listed, including internal ones.
a sorted character vector with the function names.
Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language. Wadsworth & Brooks/Cole.
ls(), ls.str(), lsf.str(),
getNamespaceExports()
Other pkg.funinfo:
auditNames(),
funArgs(),
funCalls(),
funKeywords(),
rdLabels(),
rdTitle()
funList("bedrock")funList("bedrock")
Calculates the greatest common divisor (GCD) and least common multiple (LCM) of all the values present in its arguments.
GCD(..., na.rm = FALSE) LCM(..., na.rm = FALSE)GCD(..., na.rm = FALSE) LCM(..., na.rm = FALSE)
... |
integer or logical vectors. |
na.rm |
logical; whether missing values (including NaN) are removed. |
The computation is based on the Euclidean algorithm without using the
extended version. The greatest common divisor for all numbers in the integer
vector x will be computed (the multiple GCD). Negative values are
allowed and enter via their absolute value; logical vectors are coerced
to integer.
a numeric (integer) value.
Zero behaves differently in the two functions, which is why they do not
treat it the same way. For the greatest common divisor it is
neutral - every number divides 0, so GCD(0, a) is
abs(a) and zeros can simply be dropped. For the least common
multiple it is absorbing - 0 is a multiple of every number and the
smallest non-negative one, so LCM(0, a) is 0. GCD(0, 0) and
LCM(0, 0) are both 0.
The following relation is always true:
n * m = GCD(n, m) * LCM(n, m)
It also holds when one of the values is zero, and that is the shortest way
to see why LCM(0, 6) has to be 0 rather than 6.
Other number.theory:
digitSum(),
divisors(),
factorize(),
fibonacci(),
isOdd(),
isPrime(),
primes()
GCD(12, 10) GCD(144, 233) # Fibonacci numbers are relatively prime to each other LCM(12, 10) LCM(144, 233) # = 144 * 233 # all elements will be flattened by unlist GCD(2, 3, c(5, 7) * 11) GCD(c(2*3, 3*5, 5*7)) LCM(c(2, 3, 5, 7) * 11) LCM(2*3, 3*5, 5*7) # zero is neutral for the GCD and absorbing for the LCM GCD(0, 6) LCM(0, 6) # n * m == GCD(n, m) * LCM(n, m), zero included GCD(0, 6) * LCM(0, 6)GCD(12, 10) GCD(144, 233) # Fibonacci numbers are relatively prime to each other LCM(12, 10) LCM(144, 233) # = 144 * 233 # all elements will be flattened by unlist GCD(2, 3, c(5, 7) * 11) GCD(c(2*3, 3*5, 5*7)) LCM(c(2, 3, 5, 7) * 11) LCM(2*3, 3*5, 5*7) # zero is neutral for the GCD and absorbing for the LCM GCD(0, 6) LCM(0, 6) # n * m == GCD(n, m) * LCM(n, m), zero included GCD(0, 6) * LCM(0, 6)
Lightweight helper to extract a single named argument from a list (typically
list(...)). If the argument is not present, a default value is
returned.
getDotsArg(dots, name, default = NULL)getDotsArg(dots, name, default = NULL)
dots |
named list (usually |
name |
character string, argument name. |
default |
default value if argument not present. |
the value of the argument or default.
For extracting several arguments
at once use extractArgs().
Other pkg.args:
callIf(),
extractArgs(),
mergeArgs(),
recycle()
f <- function(...) { dots <- list(...) getDotsArg(dots, "col", default = "black") } f(col = "red", lwd = 2) f(lwd = 2)f <- function(...) { dots <- list(...) getDotsArg(dots, "col", default = "black") } f(col = "red", lwd = 2) f(lwd = 2)
Functions for computing relationships between numeric intervals. All functions accept intervals as numeric vectors of length 2 or matrices with 2 columns (one interval per row). Unordered bounds are silently sorted; rows are recycled to equal length.
overlapSize(x, y) overlaps(x, y) distance(x, y) x %overlaps% yoverlapSize(x, y) overlaps(x, y) distance(x, y) x %overlaps% y
x |
a numeric vector of length 2 |
y |
a numeric vector of length 2 |
Intervals are treated as closed, i.e., . Consequently:
Two intervals sharing only a boundary point have overlap 0
but overlaps returns TRUE.
distance returns 0 whenever intervals touch or overlap.
The returned vector is always unnamed, whatever dimnames the inputs carry.
overlapnumeric vector of overlap lengths (0 if no overlap).
overlapslogical vector; TRUE if intervals share at
least one point.
distancenumeric vector of gap lengths between non-overlapping intervals (0 if overlapping or touching).
%overlaps%logical vector; operator wrapper for
overlaps().
Other data.interval:
between-operators,
range-operators
# overlap length overlapSize(c(1, 5), c(3, 7)) # 2 overlapSize(c(1, 3), c(3, 5)) # 0 (boundary only) # overlap check overlaps(c(1, 5), c(3, 7)) # TRUE overlaps(c(1, 3), c(3, 5)) # TRUE (boundary counts) overlaps(c(1, 2), c(3, 4)) # FALSE # gap distance distance(c(1, 2), c(4, 5)) # 2 distance(c(1, 5), c(3, 7)) # 0 # operator c(1, 5) %overlaps% c(3, 7) # TRUE # vectorised (matrix input) m <- matrix(c(1,3, 2,6, 5,8), ncol = 2, byrow = TRUE) overlapSize(m, c(4, 7))# overlap length overlapSize(c(1, 5), c(3, 7)) # 2 overlapSize(c(1, 3), c(3, 5)) # 0 (boundary only) # overlap check overlaps(c(1, 5), c(3, 7)) # TRUE overlaps(c(1, 3), c(3, 5)) # TRUE (boundary counts) overlaps(c(1, 2), c(3, 4)) # FALSE # gap distance distance(c(1, 2), c(4, 5)) # 2 distance(c(1, 5), c(3, 7)) # 0 # operator c(1, 5) %overlaps% c(3, 7) # TRUE # vectorised (matrix input) m <- matrix(c(1,3, 2,6, 5,8), ncol = 2, byrow = TRUE) overlapSize(m, c(4, 7))
Determines whether a vector contains at most two distinct values.
isDichotomous(x, strict = FALSE, na.rm = FALSE)isDichotomous(x, strict = FALSE, na.rm = FALSE)
x |
a vector. |
strict |
logical. If |
na.rm |
logical. If |
TRUE, FALSE, or NA if the status cannot be
determined because of missing values (see na.rm).
Other data.predicate:
flags(),
isEuclid(),
isLowCardinality(),
isNumeric(),
isWholeLike(),
isZero(),
nUnique()
isDichotomous(c(0, 1, 1)) isDichotomous(c(1, 1, 1)) isDichotomous(c(1, 1, 1), strict = TRUE) isDichotomous(c(0, 1, NA)) # NA isDichotomous(c(0, 1, NA), na.rm = TRUE) isDichotomous(c("A", "A", "B")) isDichotomous(c("A", "A", "B", "C")) isDichotomous(factor(c("A", "A", "B", "C")))isDichotomous(c(0, 1, 1)) isDichotomous(c(1, 1, 1)) isDichotomous(c(1, 1, 1), strict = TRUE) isDichotomous(c(0, 1, NA)) # NA isDichotomous(c(0, 1, NA), na.rm = TRUE) isDichotomous(c("A", "A", "B")) isDichotomous(c("A", "A", "B", "C")) isDichotomous(factor(c("A", "A", "B", "C")))
Checks whether a distance matrix corresponds to Euclidean distances.
isEuclid(x, tol = 0.0000001)isEuclid(x, tol = 0.0000001)
x |
an object of class |
tol |
numeric tolerance for detecting negative eigenvalues, relative to the largest absolute eigenvalue. |
The test is based on the eigenvalues of the double-centered squared
distance matrix . A distance matrix is
Euclidean if and only if is positive semi-definite, i.e., all
eigenvalues are non-negative (within numerical tolerance).
The tolerance is applied relative to the largest absolute
eigenvalue, so that the test is invariant to rescaling of the
distances. Note that this holds in both directions: the comparison
below uses max(abs(lambda)) without an absolute floor, so
shrinking all distances by a constant factor cannot turn a
non-Euclidean matrix into a Euclidean one.
The returned logical value carries additional diagnostic information as attributes:
eigenvalues: Eigenvalues of the centered matrix
minEigenvalue: Smallest eigenvalue
tol: Tolerance used for the test
a logical scalar. Returns TRUE if the distance matrix is
(approximately) Euclidean, otherwise FALSE.
Other data.predicate:
flags(),
isDichotomous(),
isLowCardinality(),
isNumeric(),
isWholeLike(),
isZero(),
nUnique()
d <- dist(matrix(rnorm(20), ncol = 2)) res <- isEuclid(d) res # Access diagnostics attr(res, "eigenvalues") attr(res, "minEigenvalue")d <- dist(matrix(rnorm(20), ncol = 2)) res <- isEuclid(d) res # Access diagnostics attr(res, "eigenvalues") attr(res, "minEigenvalue")
Returns TRUE if the given string looks like a local file path (absolute
or relative, Unix/Windows style), FALSE otherwise. Convenience wrapper
around the internal .detectInputType() helper.
isFilePath(x)isFilePath(x)
x |
|
logical(1) - TRUE if x is a file path, FALSE otherwise.
isUrl() for the complementary URL check.
Other file.path:
buildPath(),
findDownload(),
isUrl(),
splitPath(),
urlExists()
isFilePath("/home/user/data/file.csv") # TRUE isFilePath("~/documents/report.pdf") # TRUE isFilePath("./relative/path/file.R") # TRUE isFilePath("../other/folder/data.rds") # TRUE isFilePath("C:/Users/Hans/file.xlsx") # TRUE isFilePath("https://example.com/f.csv") # FALSEisFilePath("/home/user/data/file.csv") # TRUE isFilePath("~/documents/report.pdf") # TRUE isFilePath("./relative/path/file.R") # TRUE isFilePath("../other/folder/data.rds") # TRUE isFilePath("C:/Users/Hans/file.xlsx") # TRUE isFilePath("https://example.com/f.csv") # FALSE
Checks whether x contains at most maxUnique unique, non-missing
values. Unlike nUnique(), this stops counting as soon as the threshold
is exceeded, which makes it considerably faster for large,
high-cardinality vectors.
isLowCardinality(x, maxUnique = 12)isLowCardinality(x, maxUnique = 12)
x |
a numeric or integer vector. |
maxUnique |
integer. The threshold up to which |
a logical of length one: TRUE if x has maxUnique or fewer
unique, non-NA values, FALSE otherwise.
nUnique() for the uncapped count.
Other data.predicate:
flags(),
isDichotomous(),
isEuclid(),
isNumeric(),
isWholeLike(),
isZero(),
nUnique()
isLowCardinality(c(1, 2, 2, 3, NA)) isLowCardinality(1:100, maxUnique = 12)isLowCardinality(c(1, 2, 2, 3, NA)) isLowCardinality(1:100, maxUnique = 12)
Check whether an object is a single missing value (NA).
isNA(x)isNA(x)
x |
an object to be tested. |
This is a strict helper that returns TRUE only if x is an
atomic vector of length one and equal to NA. In contrast to
is.na(), which is vectorized, isNA is intended for
scalar checks, e.g. in conditional statements.
This function differs from is.na() in that it:
Only returns TRUE for length-one inputs
Returns a single logical value (not vectorized)
Works consistently across all NA types
logical scalar. Returns TRUE if x is a single
missing value (NA), and FALSE otherwise.
Other vector.na:
coalesceX(),
locf(),
naIf(),
naReplace()
isNA(NA) # TRUE isNA(NA_real_) # TRUE isNA(NA_integer_) # TRUE isNA(c(NA, NA)) # FALSE (length > 1) isNA(NULL) # FALSE isNA(1) # FALSE isNA(c(1, NA)) # FALSEisNA(NA) # TRUE isNA(NA_real_) # TRUE isNA(NA_integer_) # TRUE isNA(c(NA, NA)) # FALSE (length > 1) isNA(NULL) # FALSE isNA(1) # FALSE isNA(c(1, NA)) # FALSE
Validates that an object is numeric and optionally satisfies additional structural constraints such as integer-valuedness or positivity.
isNumeric( x, isIntegerValued = FALSE, isPositive = FALSE, tol = sqrt(.Machine$double.eps), na.rm = FALSE )isNumeric( x, isIntegerValued = FALSE, isPositive = FALSE, tol = sqrt(.Machine$double.eps), na.rm = FALSE )
x |
an object to be tested. |
isIntegerValued |
logical. If |
isPositive |
logical. If |
tol |
numerical tolerance used when |
na.rm |
logical. If |
The function checks:
Whether x is numeric.
Whether all values are finite.
Optional integer-like constraint via isWholeLike().
Optional positivity constraint.
This function is intended for internal validation in statistical routines.
Length validation is the responsibility of the caller and should be
performed separately with an explicit length() check.
a single logical value.
Other data.predicate:
flags(),
isDichotomous(),
isEuclid(),
isLowCardinality(),
isWholeLike(),
isZero(),
nUnique()
isNumeric(c(1, 2, 3)) isNumeric(c(1, 2.1, 3), isIntegerValued = TRUE) isNumeric(c(1, -2, 3), isPositive = TRUE) isNumeric(c(1, NA), na.rm = TRUE)isNumeric(c(1, 2, 3)) isNumeric(c(1, 2.1, 3), isIntegerValued = TRUE) isNumeric(c(1, -2, 3), isPositive = TRUE) isNumeric(c(1, NA), na.rm = TRUE)
Checks whether elements of a numeric vector are odd integers.
isOdd(x)isOdd(x)
x |
a numeric vector. |
The function first checks whether values are finite integers. Non-integer
values (e.g. 3.5), NA, NaN, or Inf return NA.
A bare logical NA is accepted and treated as a missing numeric value.
a logical vector of the same length as x. Returns TRUE
for odd integers, FALSE for even integers, and NA for
non-integer or non-finite values.
Other number.theory:
GCD-LCM,
digitSum(),
divisors(),
factorize(),
fibonacci(),
isPrime(),
primes()
isOdd(1:5) isOdd(c(2, 3, 4.5, NA, Inf))isOdd(1:5) isOdd(c(2, 3, 4.5, NA, Inf))
Determines whether integer values are prime numbers.
isPrime(x)isPrime(x)
x |
a numeric vector. Values must be finite whole numbers not
exceeding |
This function is vectorized and returns a logical vector of the same length as the input.
Internally, a fast deterministic primality test for 64-bit integers is used.
Non-integer, negative, missing, or non-finite values result in
FALSE: there the answer is known, it simply is not "prime".
a logical vector indicating whether each element of x
is a prime number, NA where x exceeds 2^53.
Values above 2^53 (9007199254740992) return NA with
a warning, because for them there is no answer to give. 2^53 is
the largest integer up to which every integer is exactly
representable; above it the representable integers thin out, so the
value that reaches the test need not be the value that was entered: R
parses 9007199254740997, which is prime, as
9007199254740996.
Every representable double above 2^53 is even, so testing the
neighbour would report FALSE for every prime beyond the
bound – silently, and with no way for the caller to notice. For larger
numbers, use gmp::isprime() with a gmp::as.bigz() or
character input.
factorize() carries the same bound but rejects the input
with an error instead. The difference is deliberate: factorize()
answers one number per call element and can refuse the call, whereas a
vectorized predicate should not let a single unrepresentable element
discard the result for all the others.
Other number.theory:
GCD-LCM,
digitSum(),
divisors(),
factorize(),
fibonacci(),
isOdd(),
primes()
isPrime(2) isPrime(1:10) isPrime(c(17, 18, 19))isPrime(2) isPrime(1:10) isPrime(c(17, 18, 19))
Returns TRUE if the given string starts with a recognised URL scheme,
FALSE otherwise. Convenience wrapper around the internal
.detectInputType() helper.
isUrl(x)isUrl(x)
x |
|
logical(1) - TRUE if x is a URL, FALSE otherwise.
For the complementary check on an existing path, see isFilePath().
Other file.path:
buildPath(),
findDownload(),
isFilePath(),
splitPath(),
urlExists()
isUrl("https://example.com/data.csv") # TRUE isUrl("ftp://files.example.org/x.zip") # TRUE isUrl("s3://my-bucket/file.parquet") # TRUE isUrl("/home/user/file.csv") # FALSE isUrl("./script.R") # FALSEisUrl("https://example.com/data.csv") # TRUE isUrl("ftp://files.example.org/x.zip") # TRUE isUrl("s3://my-bucket/file.parquet") # TRUE isUrl("/home/user/file.csv") # FALSE isUrl("./script.R") # FALSE
Checks whether values are integer-like within a numerical tolerance. Works for numeric, integer, and complex vectors.
isWholeLike( x, all = TRUE, isNonNegative = FALSE, tol = sqrt(.Machine$double.eps), na.rm = FALSE )isWholeLike( x, all = TRUE, isNonNegative = FALSE, tol = sqrt(.Machine$double.eps), na.rm = FALSE )
x |
a numeric, integer, or complex vector. |
all |
logical. If |
isNonNegative |
logical. If |
tol |
numerical tolerance for comparing to the nearest integer.
Default is |
na.rm |
logical. If |
A value is considered whole-like if the absolute difference between
the value and its nearest integer is smaller than tol.
For complex numbers, both real and imaginary parts must be whole-like;
with isNonNegative = TRUE, both parts must additionally be
non-negative.
if all = TRUE, a single logical value.
If all = FALSE, a logical vector.
Other data.predicate:
flags(),
isDichotomous(),
isEuclid(),
isLowCardinality(),
isNumeric(),
isZero(),
nUnique()
isWholeLike(c(1, 2, 3)) isWholeLike(c(1, 2.0000001), tol = 1e-6) isWholeLike(c(1, 2.5), all = FALSE) isWholeLike(c(1, -2), isNonNegative = TRUE) isWholeLike(1:5 + 0i)isWholeLike(c(1, 2, 3)) isWholeLike(c(1, 2.0000001), tol = 1e-6) isWholeLike(c(1, 2.5), all = FALSE) isWholeLike(c(1, -2), isNonNegative = TRUE) isWholeLike(1:5 + 0i)
Test if x is zero. This is done by checking if the numeric value is below the machine tolerance.
isZero(x, tol = sqrt(.Machine$double.eps), na.rm = FALSE)isZero(x, tol = sqrt(.Machine$double.eps), na.rm = FALSE)
x |
a (non-empty) numeric or complex vector of data values. |
tol |
tolerance to be used. |
na.rm |
logical, indicating whether |
logical vector of the same length as x (after optional
NA removal). Non-numeric input yields all-FALSE.
Burns, P. (2011). The R Inferno. https://www.burns-stat.com/documents/books/the-r-inferno/
Other data.predicate:
flags(),
isDichotomous(),
isEuclid(),
isLowCardinality(),
isNumeric(),
isWholeLike(),
nUnique()
# "... These are people who live in ignorance of the Floating Point Gods. # These pagans expect [...] the following to be TRUE" (Burns, 2011): (.1 - .3 / 3) == 0 # they might be helped by isZero(.1 - .3 / 3)# "... These are people who live in ignorance of the Floating Point Gods. # These pagans expect [...] the following to be TRUE" (Burns, 2011): (.1 - .3 / 3) == 0 # they might be helped by isZero(.1 - .3 / 3)
Retrieve or assign a label to an object, or to variables (columns) of a data frame.
label(x, vars = NULL) label(x, vars = NULL) <- valuelabel(x, vars = NULL) label(x, vars = NULL) <- value
x |
an object. Typically an atomic vector or a data.frame. |
vars |
optional specification of variables (columns) in a data.frame. Can be:
|
value |
a character vector of labels, or |
For atomic objects, a single label can be stored as an attribute "label".
For data frames, a label can be assigned either to the whole dataset or to
individual columns.
The function provides a unified interface for working with labels:
label(x) returns the label of an object
label(x) <- "text" sets the label of an object
label(x, vars = ...) returns labels of selected variables
label(x, vars = ...) <- value sets variable labels
Variable labels are stored as attribute "label" on each column.
Assigning NULL removes the label(s).
getter: a character scalar (object label) or a named character vector (variable labels).
setter: the modified object x.
Other label.attrs:
renameX(),
setAttr-removeAttr-keepAttr,
setNamesX()
df <- data.frame(age = 1:3, sex = c("m", "f", "m")) # Set dataset label label(df) <- "Example dataset" label(df) # Set variable labels label(df, vars = TRUE) <- c("Age in years", "Sex") label(df, vars = TRUE) # Set single variable label label(df, vars = "age") <- "Age" label(df, vars = "age") # Remove variable labels label(df, vars = TRUE) <- NULL # Atomic vector x <- 1:5 label(x) <- "Simple vector" label(x)df <- data.frame(age = 1:3, sex = c("m", "f", "m")) # Set dataset label label(df) <- "Example dataset" label(df) # Set variable labels label(df, vars = TRUE) <- c("Age in years", "Sex") label(df, vars = TRUE) # Set single variable label label(df, vars = "age") <- "Age" label(df, vars = "age") # Remove variable labels label(df, vars = TRUE) <- NULL # Atomic vector x <- 1:5 label(x) <- "Simple vector" label(x)
Performs a linear transformation of numeric data to a specified range.
Each column of x is rescaled independently.
linScale(x, low = NULL, high = NULL, newLow = 0, newHigh = 1)linScale(x, low = NULL, high = NULL, newLow = 0, newHigh = 1)
x |
a numeric vector, matrix or data frame. |
low, high
|
optional numeric vectors specifying the lower and upper
bounds of the original scale. If |
newLow, newHigh
|
numeric vectors specifying the target range.
Defaults to |
The transformation is defined as:
Constant columns (where high == low) are mapped to newLow.
If low and high are supplied, values of x outside
[low, high] are extrapolated linearly and are not clipped to the
target range.
an object of the same shape as x: a numeric vector for
vector input, otherwise a numeric matrix with the same dimensions,
where each column is linearly rescaled to the interval
[newLow, newHigh].
scale(), DescToolsX::scaleX
Other math.transform:
logit(),
percentRank(),
rankX(),
winsorize()
x <- matrix(1:10, ncol = 2) # default scaling to [0,1] linScale(x) # custom range linScale(x, newLow = -1, newHigh = 1) # using predefined bounds linScale(x, low = 1, high = 10)x <- matrix(1:10, ncol = 2) # default scaling to [0,1] linScale(x) # custom range linScale(x, newLow = -1, newHigh = 1) # using predefined bounds linScale(x, low = 1, high = 10)
In longitudinal studies it's common that individuals drop out before all responses can be obtained. Measurements obtained before the individual dropped out can be used to impute the unknown measurement(s). The last observation carried forward method is one way to impute values for the missing observations. For the last observation carried forward (LOCF) approach the missing values are replaced by the last observed value of that variable for each individual regardless of when it occurred.
locf(x)locf(x)
x |
a vector, a data.frame or a matrix containing NAs. |
locf() replaces NAs with the most recent non-NA prior to it.
The function will replace all NAs found in a vector with the last earlier value not being NA. In data frames and matrices each column is treated separately, so that values are never carried across column boundaries. Factors are supported and keep their levels and ordering.
It should be noted, that the last observation carried forward approach may result in biased estimates and may underestimate the variability.
an object of the same type and dimension as x.
Based on code by Daniel Wollschlaeger, adapted to conform to package standards; multi-column, data-frame, and factor support added by the package author.
See also the package Hmisc for less coarse imputation functions.
Other vector.na:
coalesceX(),
isNA(),
naIf(),
naReplace()
d.frm <- data.frame( day=rep(c("mon", "tue", "wed", "thu", "fri", "sat", "sun"), 4) , val=rep(c(runif(5), rep(NA,2)), 4) ) d.frm$locf <- locf( d.frm$val ) d.frmd.frm <- data.frame( day=rep(c("mon", "tue", "wed", "thu", "fri", "sat", "sun"), 4) , val=rep(c(runif(5), rep(NA,2)), 4) ) d.frm$locf <- locf( d.frm$val ) d.frm
Computes the logit transformation and its inverse for values defined on a
finite interval .
logit(x, min = 0, max = 1, eps = .Machine$double.eps, warn = FALSE) logitInv(x, min = 0, max = 1)logit(x, min = 0, max = 1, eps = .Machine$double.eps, warn = FALSE) logitInv(x, min = 0, max = 1)
x |
numeric vector. For |
min |
lower bound of the interval. Must be finite. |
max |
upper bound of the interval. Must be finite and greater than |
eps |
small positive value used to clamp probabilities away from
|
warn |
logical; if |
The logit() function maps values from to the real
line . The inverse transformation logitInv()
maps real-valued inputs back to .
The logit transformation is defined as:
where
For numerical stability, is clamped to before
applying the transformation. This prevents returning -Inf or
Inf for values exactly equal to min or max, or slightly
outside the interval due to floating point error.
If warn = TRUE, a warning is issued when such clamping occurs.
The inverse transformation is given by:
where is the input to logitInv().
Note that logitInv() does not perform clamping. This asymmetry is
intentional: plogis() is well-defined for all real inputs,
so no stabilization is required.
a numeric vector of the same length as x.
Other math.transform:
linScale(),
percentRank(),
rankX(),
winsorize()
x <- seq(0, 1, length.out = 5) z <- logit(x) logitInv(z) # Boundary values are clamped internally: # 0 -> eps, 1 -> 1 - eps logit(c(0, 0.5, 1)) # With warn = TRUE, clamping at the boundaries triggers a warning logit(c(0, 0.5, 1), warn = TRUE) # Values strictly outside the interval also trigger a warning logit(c(-0.1, 0.5, 1.1), warn = TRUE) # Custom interval x <- seq(10, 20, length.out = 5) z <- logit(x, min = 10, max = 20) logitInv(z, min = 10, max = 20)x <- seq(0, 1, length.out = 5) z <- logit(x) logitInv(z) # Boundary values are clamped internally: # 0 -> eps, 1 -> 1 - eps logit(c(0, 0.5, 1)) # With warn = TRUE, clamping at the boundaries triggers a warning logit(c(0, 0.5, 1), warn = TRUE) # Values strictly outside the interval also trigger a warning logit(c(-0.1, 0.5, 1.1), warn = TRUE) # Custom interval x <- seq(10, 20, length.out = 5) z <- logit(x, min = 10, max = 20) logitInv(z, min = 10, max = 20)
Reshape data between long and wide format using a grouping variable.
toLong(x, varNames = NULL, includeRowNames = FALSE) toWide(x, groups, by = NULL, varNames = NULL)toLong(x, varNames = NULL, includeRowNames = FALSE) toWide(x, groups, by = NULL, varNames = NULL)
x |
object to reshape. For |
varNames |
optional character vector of column names for the result. |
includeRowNames |
logical. If |
groups |
grouping vector used to define the columns in the wide result. |
by |
optional vector used to align values row-wise when reshaping to
wide format. If |
toLong() expects x to be a matrix, table, data frame, or list and
reshapes it to a long data frame representation. toWide() expects a vector
x and a grouping vector groups, and reshapes the values into one column
per group.
a reshaped object of class data.frame.
Other data.reshape:
collapseTable(),
splitAt(),
splitX(),
untable()
d.x <- read.table(header = TRUE, text = " AA BB CC DD EE FF GG 7.9 18.1 13.3 6.2 9.3 8.3 10.6 9.8 14.0 13.6 7.9 2.9 9.1 13.0 6.4 17.4 16.0 10.9 8.6 11.7 17.5 ") toLong(d.x) # to wide by row order toWide(PlantGrowth$weight, PlantGrowth$group) # to wide aligned by key set.seed(41) PlantGrowth$nr <- c(sample(12, 10), sample(12, 10), sample(12, 10)) toWide(PlantGrowth$weight, PlantGrowth$group, by = PlantGrowth$nr)d.x <- read.table(header = TRUE, text = " AA BB CC DD EE FF GG 7.9 18.1 13.3 6.2 9.3 8.3 10.6 9.8 14.0 13.6 7.9 2.9 9.1 13.0 6.4 17.4 16.0 10.9 8.6 11.7 17.5 ") toLong(d.x) # to wide by row order toWide(PlantGrowth$weight, PlantGrowth$group) # to wide aligned by key set.seed(41) PlantGrowth$nr <- c(sample(12, 10), sample(12, 10), sample(12, 10)) toWide(PlantGrowth$weight, PlantGrowth$group, by = PlantGrowth$nr)
Helper used to merge defaults with user arguments, remove forbidden argument names, and optionally warn if forbidden arguments were supplied.
mergeArgs(defaults, user, forbidden = NULL, warn = TRUE)mergeArgs(defaults, user, forbidden = NULL, warn = TRUE)
defaults |
named list of default arguments. |
user |
named list of user-supplied arguments, or |
forbidden |
character vector of argument names that are not allowed. |
warn |
logical; whether to issue a warning if forbidden arguments are removed. |
User values override defaults of the same name. Unlike
modifyList(), elements with the value NULL are
preserved (so that an explicit NULL can be passed on as an
argument value instead of silently deleting the entry).
a named list of merged arguments.
Other pkg.args:
callIf(),
extractArgs(),
getDotsArg(),
recycle()
mergeArgs(list(col = "black", lty = 1), list(col = "red")) # explicit NULL survives the merge mergeArgs(list(col = "black"), list(col = NULL))mergeArgs(list(col = "black", lty = 1), list(col = "red")) # explicit NULL survives the merge mergeArgs(list(col = "black"), list(col = NULL))
Replaces multiple substrings in a character vector simultaneously, avoiding the cascade problem where an earlier replacement becomes the target of a later one. Internally uses temporary unique tokens as an intermediate step.
mGsub(x, patterns, replacements)mGsub(x, patterns, replacements)
x |
a character vector in which substitutions are performed. |
patterns |
a character vector of substrings to search for
( |
replacements |
a character vector of replacement strings,
in the same order as |
Patterns are processed in the given order. For overlapping patterns
(e.g. "AB" and "A"), list the longer pattern first,
otherwise the shorter one consumes its characters before the longer
one is considered.
a character vector of the same length as x.
mReplace() for exact whole-element replacement.
Other string.transform:
char-ascii-conversion,
strSplitToCol(),
strSplitToDummy()
mGsub(c("foo bar", "bar foo"), c("foo", "bar"), c("bar", "foo")) # [1] "bar foo" "foo bar" # Without simultaneous replacement this would yield "foo foo" # with sequential gsub(). x <- c("A", "B", "AB", "BA") mGsub(x, patterns = c("A", "B"), replacements = c("BX", "CY"))mGsub(c("foo bar", "bar foo"), c("foo", "bar"), c("bar", "foo")) # [1] "bar foo" "foo bar" # Without simultaneous replacement this would yield "foo foo" # with sequential gsub(). x <- c("A", "B", "AB", "BA") mGsub(x, patterns = c("A", "B"), replacements = c("BX", "CY"))
Compute the midpoints between consecutive elements of a numeric vector. This is useful, for example, when positioning labels in stacked bar plots.
midx(x, inclZero = FALSE, cumulate = FALSE)midx(x, inclZero = FALSE, cumulate = FALSE)
x |
a numeric vector. |
inclZero |
logical. If |
cumulate |
logical. If |
The midpoints are defined as:
When inclZero = TRUE, the computation is performed on
c(0, x).
a numeric vector of length length(x) - 1 (or length(x)
if inclZero = TRUE) containing the midpoints. Returns an empty
numeric vector if fewer than two values are available.
Other vector.window:
moveAvg(),
quot()
x <- c(1, 3, 6, 7) midx(x) midx(x, inclZero = TRUE) midx(x, inclZero = TRUE, cumulate = TRUE) # Example: label positions in a stacked bar plot tab <- matrix(c(401,216,221,254,259,169), nrow = 2, byrow = TRUE) b <- barplot(tab, beside = FALSE, horiz = TRUE) xpos <- t(apply(tab, 2, midx, inclZero = TRUE, cumulate = TRUE)) text(x = xpos, y = b, labels = t(tab), col = "red")x <- c(1, 3, 6, 7) midx(x) midx(x, inclZero = TRUE) midx(x, inclZero = TRUE, cumulate = TRUE) # Example: label positions in a stacked bar plot tab <- matrix(c(401,216,221,254,259,169), nrow = 2, byrow = TRUE) b <- barplot(tab, beside = FALSE, horiz = TRUE) xpos <- t(apply(tab, 2, midx, inclZero = TRUE, cumulate = TRUE)) text(x = xpos, y = b, labels = t(tab), col = "red")
Computes a simple moving average (running mean) of a numeric vector or time series.
moveAvg( x, order, align = c("center", "left", "right"), endrule = c("NA", "keep", "constant", "trim") )moveAvg( x, order, align = c("center", "left", "right"), endrule = c("NA", "keep", "constant", "trim") )
x |
a univariate numeric vector or |
order |
a single positive integer giving the window width.
Must satisfy |
align |
a character string controlling how the window is positioned relative to each output value:
|
endrule |
a character string indicating how boundary values (where a full window is unavailable) are handled:
|
The core computation uses cumulative sums for O(n) efficiency:
where the summation range depends on align.
Even-order windows and center alignment
For even order, centering is ambiguous. This implementation
averages the two adjacent right-aligned windows of width order,
which is the convention used by forecast::ma().
Boundary handling (endrule = "trim")
At the boundaries the window is contracted to include only the
available observations. For center alignment with even order,
the boundary window width at position is
.
Missing values
NA in x propagates through cumsum() and will
produce NA in all moving-average values whose window contains
that observation. There is no na.rm option; pre-filter with
x[!is.na(x)] if needed (note this changes index positions).
a vector of the same length and class as x, with
NA at boundary positions unless endrule specifies
otherwise.
zoo::rollmean(), forecast::ma(), runmed()
Other vector.window:
midx(),
quot()
moveAvg(AirPassengers, order = 5) moveAvg(AirPassengers, order = 5, endrule = "trim") moveAvg(AirPassengers, order = 4, align = "right", endrule = "constant")moveAvg(AirPassengers, order = 5) moveAvg(AirPassengers, order = 5, endrule = "trim") moveAvg(AirPassengers, order = 4, align = "right", endrule = "constant")
Replaces elements of a character vector based on a lookup defined by two parallel vectors. Each element exactly matching a pattern is replaced with the corresponding replacement.
mReplace(x, patterns, replacements)mReplace(x, patterns, replacements)
x |
a character vector whose elements are to be replaced. |
patterns |
a character vector of values to search for. |
replacements |
a character vector of replacement values,
in the same order as |
a character vector of the same length as x, with matching
elements replaced. Non-matching elements are returned unchanged.
mGsub() for substring replacement.
Other data.recode:
asBinary(),
combLevels(),
dummy(),
nf(),
recodeX(),
revCode(),
stringsAsFactors()
mReplace(c("a", "b", "c", "d"), c("a", "c"), c("A", "C")) # [1] "A" "b" "C" "d"mReplace(c("a", "b", "c", "d"), c("a", "c"), c("A", "C")) # [1] "A" "b" "C" "d"
Merge multiple data frames by row names, or do other versions of database join operations.
multMerge(..., all.x = TRUE, all.y = TRUE, by = NULL)multMerge(..., all.x = TRUE, all.y = TRUE, by = NULL)
... |
data frames to be coerced to one. |
all.x |
logical; if |
all.y |
logical; analogous to |
by |
column used for merging, if this is not defined rownames will be used by default. The column must be included in all the provided data frames and its values must be unique within each data frame. Note that the restored key column is of type character. |
a data frame. The rows are sorted according to the appearance of previously unobserved rownames. So the rownames appearing in the first data frame are first, then the rownames in the second data frame, which have no corespondence in the first data frame and so on. The columns are the remaining columns in x1 and then those in x2 and then those in x3. The result has the row names resulting from the merge.
Other data.append:
appendEnum(),
appendRowNames(),
appendX()
x1 <- setNamesX(data.frame(v = letters[1:6], w = 1:6), rownames = LETTERS[1:6]) x2 <- setNamesX(data.frame(v = letters[2:4], ww = 11:13), rownames = LETTERS[2:4]) x3 <- setNamesX(data.frame(v = letters[c(1, 3, 5, 7, 10)], wwww = 22:26), rownames = LETTERS[c(1, 3, 5, 7, 10)]) # the default merges on the row names and returns their union, # with NA wherever a frame has no such row multMerge(x1, x2, x3) # v is not a key in the call above and is simply carried along from # each frame; here it becomes the key instead multMerge(x1, x2, x3, by = "v")x1 <- setNamesX(data.frame(v = letters[1:6], w = 1:6), rownames = LETTERS[1:6]) x2 <- setNamesX(data.frame(v = letters[2:4], ww = 11:13), rownames = LETTERS[2:4]) x3 <- setNamesX(data.frame(v = letters[c(1, 3, 5, 7, 10)], wwww = 22:26), rownames = LETTERS[c(1, 3, 5, 7, 10)]) # the default merges on the row names and returns their union, # with NA wherever a frame has no such row multMerge(x1, x2, x3) # v is not a key in the call above and is simply carried along from # each frame; here it becomes the key instead multMerge(x1, x2, x3, by = "v")
Replaces specified values in a vector with NA, in the manner of
SQL's NULLIF. This is the complementary operation to
coalesceX().
naIf(x, values)naIf(x, values)
x |
a vector. |
values |
values to be replaced by |
a vector of the same type as x.
Other vector.na:
coalesceX(),
isNA(),
locf(),
naReplace()
naIf(c(1, 2, 99, 3, 99), 99) naIf(c("a", "b", "n/a", ""), c("n/a", ""))naIf(c(1, 2, 99, 3, 99), 99) naIf(c("a", "b", "n/a", ""), c("n/a", ""))
Replaces NA values in a vector or factor with a specified value.
naReplace(x, value) ## Default S3 method: naReplace(x, value) ## S3 method for class 'factor' naReplace(x, value)naReplace(x, value) ## Default S3 method: naReplace(x, value) ## S3 method for class 'factor' naReplace(x, value)
x |
a vector or factor. |
value |
the replacement value. For factors, a single character string. |
For factors (including ordered factors), value is appended as a
new level at the last position if it is not already present. If
value is an existing level, the missing values are simply filled
with it.
an object of the same class as x with NA values
replaced by value.
Other vector.na:
coalesceX(),
isNA(),
locf(),
naIf()
# default: numeric vector naReplace(c(1, NA, 3), 0) # character vector naReplace(c("a", NA, "c"), "missing") # unordered factor naReplace(factor(c("a", "b", NA)), "missing") # ordered factor: the new level is appended at the end naReplace(factor(c("low", "high", NA), levels = c("low", "high"), ordered = TRUE), "unknown")# default: numeric vector naReplace(c(1, NA, 3), 0) # character vector naReplace(c("a", NA, "c"), "missing") # unordered factor naReplace(factor(c("a", "b", NA)), "missing") # ordered factor: the new level is appended at the end naReplace(factor(c("low", "high", NA), levels = c("low", "high"), ordered = TRUE), "unknown")
Converts an object to numeric by first coercing it to a factor and then
to numeric. This is useful whenever a categorical or character variable
needs a purely numeric stand-in – for example, as input to functions
that require numeric data (distance calculations, correlation matrices,
some modelling routines), or to obtain a compact, deterministic
small-integer code for an ordinal variable by passing an explicit
levels order.
nf(x, ...)nf(x, ...)
x |
a vector to be converted. |
... |
additional arguments passed to |
This function is a shorthand for as.numeric(factor(x, ...)).
Note that the resulting numeric values correspond to the internal
factor levels, not the original numeric values. In particular, for
character vectors holding numbers the codes follow the alphabetical
level order (see the last example) – use
as.numeric(as.character(x)) to recover the values themselves.
a numeric vector corresponding to the integer codes of the factor levels.
Other data.recode:
asBinary(),
combLevels(),
dummy(),
mReplace(),
recodeX(),
revCode(),
stringsAsFactors()
nf(c("a", "b", "a")) nf(c("low", "medium", "high"), levels = c("low", "medium", "high")) # caution: codes, not values nf(c("10", "2")) # 1 2, not 10 2nf(c("a", "b", "a")) nf(c("low", "medium", "high"), levels = c("low", "medium", "high")) # caution: codes, not values nf(c("10", "2")) # 1 2, not 10 2
Vectorized conversion between positional numeral systems (bases 2-36),
plus Roman-numeral parsing. The convenience wrappers cover the most
common cases; baseToBase() handles any combination of bases.
hexToDec(x) decToHex(x) octToDec(x) decToOct(x) binToDec(x) decToBin(x) romanToInt(x) baseToBase(x, from, to, width = NULL)hexToDec(x) decToHex(x) octToDec(x) decToOct(x) binToDec(x) decToBin(x) romanToInt(x) baseToBase(x, from, to, width = NULL)
x |
a vector of numbers or character strings representing values in
the input base. For |
from |
a single integer in [2, 36] specifying the input base
( |
to |
a single integer in [2, 36] specifying the output base
( |
width |
a single non-negative integer or |
a vector of the same length as x:
binToDec(), octToDec(), hexToDec(),
romanToInt() - integer or numeric vector.
decToHex() - object of class hexmode().
decToOct() - numeric vector (octal digit string coerced to
numeric).
decToBin(), baseToBase() - character vector
(uppercase digits).
NA input always produces NA output.
All specialist functions are thin wrappers around baseToBase():
| Function | Equivalent call | Returns |
binToDec(x) |
baseToBase(x, 2, 10) |
integer |
decToBin(x) |
baseToBase(x, 10, 2) |
character |
octToDec(x) |
baseToBase(x, 8, 10) |
integer |
decToOct(x) |
baseToBase(x, 10, 8) |
numeric (octal digits) |
hexToDec(x) |
baseToBase(x, 16, 10) |
integer |
decToHex(x) |
baseToBase(x, 10, 16) |
hexmode
|
hexToDec() additionally strips a leading # from CSS-style
colour strings.
romanToInt() converts Roman numeral strings (e.g. "XIV") to
integers. Input is trimmed and upper-cased before parsing; invalid strings
return NA. See also base R's as.roman() for the
reverse direction.
baseToBase() uses strtoi() internally, which operates
on long int. On 32-bit platforms values
above may silently return NA.
decToBin() applies the same cap
explicitly (values > 536870911 become NA).
strtoi(), as.hexmode(),
as.octmode(), as.roman()
# binary decToBin(c(0, 1, 17, 255)) binToDec(c("0", "1", "10001", "11111111")) # octal decToOct(c(8, 64, 255)) octToDec(c(10, 100, 377)) # hexadecimal (CSS colour strings are also accepted by hexToDec) decToHex(c(0, 255, 65535)) hexToDec(c("FF", "ff", "#1A2B3C")) # Roman numerals romanToInt(c("I", "IV", "XIV", "MCMXCIX")) # 1, 4, 14, 1999 romanToInt("invalid") # NA # baseToBase: general case baseToBase("FF", from = 16, to = 10) # 255 baseToBase("255", from = 10, to = 16) # "FF" baseToBase("11111111", from = 2, to = 10) # 255 baseToBase("1A3F", from = 16, to = 2) # binary expansion baseToBase("Z9", from = 36, to = 10) # base-36 -> decimal # fixed-width padding (useful for bit-pattern alignment) baseToBase(c(0, 7, 255), from = 10, to = 2, width = 8) # vectorized over x baseToBase(c("A", "B", "FF"), from = 16, to = 10)# binary decToBin(c(0, 1, 17, 255)) binToDec(c("0", "1", "10001", "11111111")) # octal decToOct(c(8, 64, 255)) octToDec(c(10, 100, 377)) # hexadecimal (CSS colour strings are also accepted by hexToDec) decToHex(c(0, 255, 65535)) hexToDec(c("FF", "ff", "#1A2B3C")) # Roman numerals romanToInt(c("I", "IV", "XIV", "MCMXCIX")) # 1, 4, 14, 1999 romanToInt("invalid") # NA # baseToBase: general case baseToBase("FF", from = 16, to = 10) # 255 baseToBase("255", from = 10, to = 16) # "FF" baseToBase("11111111", from = 2, to = 10) # 255 baseToBase("1A3F", from = 16, to = 2) # binary expansion baseToBase("Z9", from = 36, to = 10) # base-36 -> decimal # fixed-width padding (useful for bit-pattern alignment) baseToBase(c(0, 7, 255), from = 10, to = 2, width = 8) # vectorized over x baseToBase(c("A", "B", "FF"), from = 16, to = 10)
Returns the number of unique vector elements.
nUnique(x, na.rm = FALSE)nUnique(x, na.rm = FALSE)
x |
a vector. |
na.rm |
logical. Should missing values ( |
an integer of length one.
nlevels(), isLowCardinality() to check whether x
has at most a given number of unique values, without counting
all of them first.
Other data.predicate:
flags(),
isDichotomous(),
isEuclid(),
isLowCardinality(),
isNumeric(),
isWholeLike(),
isZero()
nUnique(c(1, 1, 2, 3)) nUnique(c(1, 1, 2, NA)) nUnique(c(1, 1, 2, NA), na.rm = TRUE)nUnique(c(1, 1, 2, 3)) nUnique(c(1, 1, 2, NA)) nUnique(c(1, 1, 2, NA), na.rm = TRUE)
Returns all non-zero elements of a vector. Zeroness is determined by
isZero(), i.e. within a numerical tolerance.
nz(x, tol = sqrt(.Machine$double.eps))nz(x, tol = sqrt(.Machine$double.eps))
x |
a numeric vector. |
tol |
tolerance passed to |
NA elements are not considered zero and are retained in the
result.
a vector containing only the non-zero elements of x.
Other vector.utils:
unwhich()
nz(c(0, 1, 2, 0, 3)) nz(c(1e-20, 1, NA))nz(c(0, 1, 2, 0, 3)) nz(c(1e-20, 1, NA))
Downloads an Excel file from a remote server and imports it as a data frame. Optionally processes a documentation sheet to assign variable labels and convert variables into factors with labeled levels.
openDataObject(name, url = NULL, doc = NULL, ...)openDataObject(name, url = NULL, doc = NULL, ...)
name |
character string. File name including extension (e.g. |
url |
character string. Base URL where the file is located.
Defaults to |
doc |
list or |
... |
additional arguments passed to |
The function downloads the Excel file to a temporary location and reads the first sheet as the main dataset.
If a documentation sheet is available, it is expected to contain columns such as:
Variable name
Description (label)
Codes (e.g. "1=Male | 2=Female")
Scale ("nominal", "ordinal", etc.)
Variables with scale "nominal" or "ordinal" are converted to
factors. Data values without a matching entry in the codes column become
NA.
a data.frame containing the imported data. If metadata is available:
variables may be converted to factors (nominal/ordinal).
factor levels are labeled using provided codes.
variable labels are assigned using label().
Other label.import:
dataDescription()
# the file is downloaded from a remote repository, so the examples # need an internet connection and fail gracefully without one # load the dataset with automatic metadata detection try(openDataObject("beauty.xlsx")) # load it without metadata processing try(openDataObject("beauty.xlsx", doc = NA))# the file is downloaded from a remote repository, so the examples # need an internet connection and fail gracefully without one # load the dataset with automatic metadata detection try(openDataObject("beauty.xlsx")) # load it without metadata processing try(openDataObject("beauty.xlsx", doc = NA))
Implements a logic to run pairwise calculations on the columns of a data.frame or a matrix.
pairApply(x, FUN = NULL, ..., symmetric = FALSE)pairApply(x, FUN = NULL, ..., symmetric = FALSE)
x |
a list, a data.frame or a matrix with columns to be processed pairwise. |
FUN |
a function (or the name of a function) to be calculated. It is assumed, that the first 2 arguments denominate x and y, and that it returns a single numeric value. |
... |
the dots are passed to FUN. |
symmetric |
logical. Does the function yield the same result for FUN(x,
y) and FUN(y, x)? |
This code is based on the logic of cor() and extended for asymmetric
functions. Cell [i, j] of the result contains
FUN(x[[i]], x[[j]], ...), so the first argument of FUN
corresponds to the row variable and the second to the column variable.
a matrix with the results of FUN.
Other combinatorics:
combN(),
combPairs(),
combSet(),
permn(),
randGroupSplit(),
sampleX()
# build a dataset set.seed(1) d.sub <- transform( data.frame( X1 = rnorm(n <- 300), X3 = rnorm(n)), X2 = 0.8*X1 + rnorm(n), X4 = 0.5*X3 + rnorm(n) ) pairApply(d.sub, FUN = cor, method="spearman") # user defined functions are ok as well pairApply(d.sub, FUN = function(x,y) wilcox.test(as.numeric(x), as.numeric(y))$p.value, symmetric=TRUE)# build a dataset set.seed(1) d.sub <- transform( data.frame( X1 = rnorm(n <- 300), X3 = rnorm(n)), X2 = 0.8*X1 + rnorm(n), X4 = 0.5*X3 + rnorm(n) ) pairApply(d.sub, FUN = cor, method="spearman") # user defined functions are ok as well pairApply(d.sub, FUN = function(x,y) wilcox.test(as.numeric(x), as.numeric(y))$p.value, symmetric=TRUE)
A parser for simple SAS dataline command texts. A data.frame is being
built with the columnnames listed in the input section.
parseSasDatalines(x, validateNames = FALSE)parseSasDatalines(x, validateNames = FALSE)
x |
a single character string containing a SAS DATA step with a DATALINES, CARDS, or CARDS4 block. |
validateNames |
logical. If |
The SAS function DATA is designed for quickly creating a dataset from
scratch. The whole step normally consists out of the DATA part
defining the name of the dataset, an INPUT line declaring the
variables and a DATALINES command followed by the values.
The
default delimiter used to separate the different variables is a space (thus
each variable should be one word). The $ after the variable name indicates
that the variable preceding contain character values and not numeric values.
Without specific instructions, SAS assumes that variables are numeric. The
function will fail, if it encounters a character in the place of an expected
numeric value.
Each new row in datalines will create a corresponding
unique row in the dataset. Notice that a ; is not needed after every row,
rather it is included at the end of the entire data step.
More complex command structures, i.e. other delimiters (dlm), in the
INPUT-section are not (yet) supported.
Only free-format (list) input is supported. The following SAS features are intentionally rejected with an informative error:
Column pointers (@, @)
Column input (e.g. var 1-10)
Formatted input (:)
Character values must not contain spaces or quotes; scan-based parsing splits on whitespace and does not handle quoted strings.
a data.frame with column names taken from the INPUT statement.
The attribute sas_dataset_name carries the DATA step name.
For DATA _NULL_ the data is still parsed and returned; the caller
decides what to do with it (matching SAS semantics).
SAS missing-value markers (.) are converted to NA.
Other file.io:
pdfManual(),
peekFile(),
readDownload()
sas_code <- " data mydata; input name $ age score; datalines; Alice 30 95.5 Bob 25 88.0 ; " df <- parseSasDatalines(sas_code)sas_code <- " data mydata; input name $ age score; datalines; Alice 30 95.5 Bob 25 88.0 ; " df <- parseSasDatalines(sas_code)
PDF versions of the manual are usually not included as vignettes in R
packages. Still this format is convenient for reading and doing full text
search.
This function creates the appropriate link to the pdf file on
CRAN and opens the pdf manual in a browser window.
pdfManual(package)pdfManual(package)
package |
package name (symbol or character). |
A warning (not an error) is issued if the package is not installed locally, as the manual may well exist on CRAN anyway.
the URL of the PDF manual, invisibly. Called for its side effect of opening the browser.
Other file.io:
parseSasDatalines(),
peekFile(),
readDownload()
# opens a browser window, hence only run in an interactive session if (interactive()) { pdfManual(DescToolsX) pdfManual("bedrock") }# opens a browser window, hence only run in an interactive session if (interactive()) { pdfManual(DescToolsX) pdfManual("bedrock") }
Read the first n data rows of a delimited text file and return
the result as a base R data.frame (a kind of head() for files).
peekFile(file, n = 10, ..., output = c("data.frame", "tibble"))peekFile(file, n = 10, ..., output = c("data.frame", "tibble"))
file |
character string specifying the file name. |
n |
integer specifying the number of data rows to read, defaults to 10. |
... |
additional arguments passed to
|
output |
character, either |
This function is intended for quickly inspecting large text files,
including compressed files supported by readr::read_delim().
Column types are guessed from the previewed rows only (the default
guess_max equals n). If early rows are not representative,
supply a larger guess_max via the dots.
a data.frame or a tibble (according to output)
containing the first n data rows of the file.
readr::read_delim(), toBaseR(), head(),
Other file.io:
parseSasDatalines(),
pdfManual(),
readDownload()
# a small file to look into fn <- tempfile(fileext = ".csv") write.csv(iris, fn, row.names = FALSE) if (requireNamespace("readr", quietly = TRUE)) { peekFile(fn, delim = ",") # unrepresentative early rows: guess types over more lines peekFile(fn, n = 5, delim = ",", guess_max = 150) } unlink(fn)# a small file to look into fn <- tempfile(fileext = ".csv") write.csv(iris, fn, row.names = FALSE) if (requireNamespace("readr", quietly = TRUE)) { peekFile(fn, delim = ",") # unrepresentative early rows: guess types over more lines peekFile(fn, n = 5, delim = ",", guess_max = 150) } unlink(fn)
Computes the percent rank of each element in a numeric vector. The percent rank is defined as:
where is the number of non-missing observations.
percentRank(x)percentRank(x)
x |
a numeric (or comparable) vector. |
This corresponds to the definition used in SQL and
dplyr::percent_rank().
The smallest value in x receives a percent rank of 0, and the
largest value receives a percent rank of 1 (if there are at least two
non-missing values).
Ties are handled using ties.method = "min" via rankX(),
meaning tied values receive the same minimal rank.
Missing values (NA) are preserved in the output.
If x contains fewer than two non-missing values, all results
are NA.
a numeric vector of the same length as x, containing values
between 0 and 1.
Other math.transform:
linScale(),
logit(),
rankX(),
winsorize()
x <- c(10, 20, 20, 30) percentRank(x) # With ties x <- c(1, 2, 2, 3) percentRank(x) # With missing values x <- c(3, NA, 1, 2) percentRank(x) # Single non-missing value percentRank(c(5, NA, NA))x <- c(10, 20, 20, 30) percentRank(x) # With ties x <- c(1, 2, 2, 3) percentRank(x) # With missing values x <- c(3, NA, 1, 2) percentRank(x) # Single non-missing value percentRank(c(5, NA, NA))
Returns all distinct permutations of a vector. Repeated values in x
are treated as indistinguishable, so duplicated permutations are not returned.
permn(x, sorted = FALSE)permn(x, sorted = FALSE)
x |
atomic vector. Missing values are not supported. |
sorted |
logical scalar. If |
a matrix containing all distinct permutations of x, one
permutation per row.
Other combinatorics:
combN(),
combPairs(),
combSet(),
pairApply(),
randGroupSplit(),
sampleX()
permn(letters[2:5]) permn(2:5) # repeated elements are handled as indistinguishable permn(c("a", "b", "c", "a"))permn(letters[2:5]) permn(2:5) # repeated elements are handled as indistinguishable permn(c("a", "b", "c", "a"))
An extended artificial dataset inspired by a similar dataset pizza.sav in Arbeitsbuch zur deskriptiven und induktiven Statistik by Toutenburg et al. The data describe a pizza delivery service in London serving three areas, each record being one order and its associated characteristics.
PizzaPizza
A data frame with 1209 observations on 22 variables:
integer, index of the record, complete by construction.
date of the delivery.
numeric, the week of the year.
numeric, the day of the week.
factor with the levels Brent, Camden and
Westminster.
integer, the number of pizzas delivered.
logical, TRUE if a rebate was given.
numeric, the total price of the pizzas delivered.
factor with three levels, the operator taking the order.
factor with seven levels, the driver delivering the order.
numeric, the delivery time in minutes.
numeric, the temperature in degrees Celsius on delivery.
integer, 1 if wine was ordered, 0 if not.
integer, 1 if wine was delivered, 0 if not.
logical, TRUE if a wrong pizza was delivered.
ordered factor with the levels low < medium < high, the
quality of the pizza on delivery.
integer, 1 if the order was vegetarian, 0 if not.
numeric, the Net Promoter Score from 1 to 10, an ordinal customer rating.
integer, 1 if a complaint was filed, 0 if not.
character, the type of pizza, e.g. italian, american,
gourmet or vegan.
character, the order channel, app, web or phone.
numeric, the tip in monetary units.
Compared to the original dataset, this extended version includes additional behavioural and outcome variables such as customer satisfaction, Net Promoter Score (NPS), complaints, dietary choices and tipping behaviour. These variables are generated using probabilistic models to resemble realistic business data, including noise, imperfect relationships and heterogeneous customer behaviour.
The dataset is designed to be realistically complex. It contains the data
types commonly met in practice: numerics, integers, factors, ordered factors,
logicals, characters and dates. Missing values occur both systematically and
at random, in every variable except index.
The variable nps is a simulated Net Promoter Score from 1 to 10,
calibrated to resemble realistic customer feedback distributions, including
asymmetric lower-tail behaviour.
The variable complaint is generated using a probabilistic model depending
on delivery time, order correctness and additional noise, ensuring that
complaints are not deterministically linked to single factors.
The variable tip is based on a percentage of the order price and is
influenced by customer satisfaction (nps), delivery performance and
driver-specific effects. Tips are zero for complaints or very low
satisfaction, and otherwise increase monotonically with customer
satisfaction while retaining stochastic variation.
Overall, the dataset is designed to provide a realistic benchmark for statistical modelling, including classification (binary and ordinal), regression and performance evaluation, e.g. ROC curves and AUC with confidence intervals.
Every variable carries a label attribute with its description, so that
the labels can be used in tables and plots without repeating them in the
code.
Simulated data.
Toutenburg H, Schomaker M, Wissmann M, Heumann C (2009): Arbeitsbuch zur deskriptiven und induktiven Statistik Springer, Berlin Heidelberg.
Other datasets:
Cards,
Roulette,
Tarot,
readCourseData()
str(bedrock::Pizza) summary(bedrock::Pizza$delivery_min) table(bedrock::Pizza$area, bedrock::Pizza$channel) # the missing values are part of the design colSums(is.na(bedrock::Pizza))str(bedrock::Pizza) summary(bedrock::Pizza$delivery_min) table(bedrock::Pizza$area, bedrock::Pizza$channel) # the missing values are part of the design colSums(is.na(bedrock::Pizza))
Four small utilities for the written form of a number, as opposed to its value.
nDec(x) maxDec(x) prec(x) frac(x)nDec(x) maxDec(x) prec(x) frac(x)
x |
a numeric vector, or a character vector of numbers as written. |
nDec() returns the number of decimal places of every element.maxDec() returns the largest of those numbers.prec() returns the precision, the smallest positional value of the last
significant digit found in x (e.g. 0.001 for 3.142).frac() returns the fractional part.
nDec() and maxDec() count what is printed: the input is converted
with as.character(), an exponent is discarded, and the digits behind the
last decimal separator are counted. A number that R chooses to print in
scientific notation therefore has no decimal places, nDec(1e-300) is 0,
and trailing zeros of a numeric are gone before counting, as 1.50 and
1.5 are the same number. Pass the values as character strings to count
them as written.
Where R switches to scientific notation is R's decision, not this
function's, and it has moved between versions: up to R 4.2 as.character()
followed options(scipen=), since R 4.3 it writes the shortest
representation that reads back as the same number. A value near that switch,
such as 0.00001, may therefore count five decimals or none, depending on
the R version. Pass it as a character string to fix the count.
Both a period and a comma are accepted as the decimal separator of a
character input, the last one in the string deciding, so that a thousands
separator does not distort the count. Numeric input always arrives with a
period, whatever getOption("OutDec") says.
maxDec(x) is the maximum of nDec(x), missing values removed, and 0
when nothing is left to count.
prec() works on the value rather than on its written form and reports the
position of the last significant digit across the whole vector, not one
value per element. For input that is exact in decimal it is
10^-maxDec(x).
frac() discards the sign, the fractional part of -1.25 being 0.25, as
the sign belongs to the integer part of the number. To read the decimals as
an integer, scale and round the result, round(1e4 * frac(x)) for the first
four of them.
nDec(): an integer vector of the same length as x;
NA elements yield NA.
maxDec(): a single integer value, 0 if x has no
non-missing element with decimals.
prec(): a single numeric value, the finest precision found
across all (non-missing) elements of x. Returns 1 if all values
are zero and NA if no non-missing values are left.
frac(): a numeric vector of the same length as x.
format.info(), as.integer(), trunc()
x <- rnorm(5)*100 x frac(x) # the first four decimal digits, as an integer round(1e4 * frac(x)) # the sign belongs to the integer part frac(c(-1.25, 1.25)) ## [1] 0.25 0.25 nDec(c(1.25, 1.8, 12.0, 1.00000)) ## [1] 2 1 0 0 # the same numbers, summarised maxDec(c(1.25, 1.8, 12.0, 1.00000)) ## [1] 2 x <- c("0.0000", "0", "159.283", "1.45e+10", "1.4599E+10" ) nDec(x) prec(as.numeric(x)) # trailing zeros survive in a character input, but not in a numeric one nDec("1.500") ## [1] 3 nDec(1.500) ## [1] 1x <- rnorm(5)*100 x frac(x) # the first four decimal digits, as an integer round(1e4 * frac(x)) # the sign belongs to the integer part frac(c(-1.25, 1.25)) ## [1] 0.25 0.25 nDec(c(1.25, 1.8, 12.0, 1.00000)) ## [1] 2 1 0 0 # the same numbers, summarised maxDec(c(1.25, 1.8, 12.0, 1.00000)) ## [1] 2 x <- c("0.0000", "0", "159.283", "1.45e+10", "1.4599E+10" ) nDec(x) prec(as.numeric(x)) # trailing zeros survive in a character input, but not in a numeric one nDec("1.500") ## [1] 3 nDec(1.500) ## [1] 1
Computes all prime numbers less than or equal to each value in n.
primes(n)primes(n)
n |
a numeric vector of positive whole numbers, none exceeding 100,000,000. |
The function is vectorized over n. For a single value, the primes
are returned as an integer vector; for several values, a named list is
returned, with names corresponding to the input values.
an integer vector containing the prime numbers less than or equal
to n in ascending order if n is a single number,
otherwise a named list of such vectors.
n may not exceed 100,000,000. The limit is a practical one, not a
limit of the type: the sieve of Eratosthenes needs one bit per candidate
and one integer per prime found, which at 100 million comes to roughly
12.5 MB for the sieve, 23 MB for the 5,761,455 primes, and a peak below
about 70 MB once the copy into R is counted. At
.Machine$integer.max the same three figures are 268 MB,
105,097,565 primes for 420 MB, and a peak beyond a gigabyte - which is
why the integer limit is not a sensible bound here. A substantially
larger range would call for a segmented sieve rather than for a larger
allocation.
Other number.theory:
GCD-LCM,
digitSum(),
divisors(),
factorize(),
fibonacci(),
isOdd(),
isPrime()
primes(10) primes(c(5, 10)) # the number of primes below a limit length(primes(1e6))primes(10) primes(c(5, 10)) # the number of primes below a limit length(primes(1e6))
Prints a character matrix to the console with configurable alignment, column spacing, optional row/column names, optional cli-based styling, and automatic splitting into column blocks if the output exceeds the console width.
printCharMatrix( m, align = "right", sep = 2, showRowNames = TRUE, showColNames = TRUE, useCliStyle = FALSE, width = getOption("width") )printCharMatrix( m, align = "right", sep = 2, showRowNames = TRUE, showColNames = TRUE, useCliStyle = FALSE, width = getOption("width") )
m |
a matrix (or object coercible to a matrix) containing values that will be converted to character for display. |
align |
character vector specifying alignment of cell contents,
either |
sep |
integer. Number of spaces between columns. Default is |
showRowNames |
logical. Should row names be printed? Default is |
showColNames |
logical. Should column names be printed? Default is |
useCliStyle |
logical. If |
width |
integer. Maximum output width (in characters). Defaults to
|
The function formats all entries as character strings and computes column widths
dynamically. NA entries are shown as "NA". If the full table does
not fit into the specified width, it is split column-wise into multiple
blocks (cell contents themselves are never wrapped). In this case, row names and
column headers are repeated for each block.
If a single column is wider than width, that column is printed on its own
and the requested width is deliberately exceeded, since a column cannot be
split further.
Alignment is applied per column, and spacing between columns is controlled via
sep. The function is designed as a lightweight alternative to
print.data.frame() with more control over formatting, making it suitable
for reporting outputs in packages.
invisibly returns NULL. The formatted table is printed to the console.
Other data.print:
columnWrap()
m <- matrix(c( "50.575","50.543","45.207", "49.900","51.400","44.300", "5.106","8.192","10.197" ), nrow = 3, byrow = TRUE) rownames(m) <- c("mean","median","sd") colnames(m) <- c("Brent","Camden","Westminster") # Default (right-aligned) printCharMatrix(m) # Left-aligned with custom spacing printCharMatrix(m, align = "left", sep = 4) # With CLI styling (requires cli package) if (requireNamespace("cli", quietly = TRUE)) { printCharMatrix(m, useCliStyle = TRUE) } # Force splitting into column blocks by reducing width printCharMatrix(m, width = 20)m <- matrix(c( "50.575","50.543","45.207", "49.900","51.400","44.300", "5.106","8.192","10.197" ), nrow = 3, byrow = TRUE) rownames(m) <- c("mean","median","sd") colnames(m) <- c("Brent","Camden","Westminster") # Default (right-aligned) printCharMatrix(m) # Left-aligned with custom spacing printCharMatrix(m, align = "left", sep = 4) # With CLI styling (requires cli package) if (requireNamespace("cli", quietly = TRUE)) { printCharMatrix(m, useCliStyle = TRUE) } # Force splitting into column blocks by reducing width printCharMatrix(m, width = 20)
Determines whether points lie inside a polygon. Points located exactly on polygon edges or vertices are treated as inside.
ptInPoly(x, y, polyX, polyY)ptInPoly(x, y, polyX, polyY)
x |
numeric vector of x-coordinates of the query points. |
y |
numeric vector of y-coordinates of the query points. |
polyX |
numeric vector of x-coordinates of the polygon vertices. |
polyY |
numeric vector of y-coordinates of the polygon vertices. |
The function uses a numerically stable angle summation algorithm implemented in C++ via Rcpp.
The polygon is implicitly closed (last vertex connects to the first).
The polygon is assumed to be non-self-intersecting.
Numerical robustness is ensured via epsilon-based comparisons.
an integer vector of length length(x):
point is outside the polygon.
point is inside the polygon or on its boundary.
# Define a square px <- c(0, 1, 1, 0) py <- c(0, 0, 1, 1) # Query points x <- c(0.5, 1.5, 0, 0.5) y <- c(0.5, 0.5, 0, 1) ptInPoly(x, y, px, py)# Define a square px <- c(0, 1, 1, 0) py <- c(0, 0, 1, 1) # Query points x <- c(0.5, 1.5, 0, 0.5) y <- c(0.5, 0.5, 0, 1) ptInPoly(x, y, px, py)
Returns suitably lagged and iterated quotients.
quot(x, lag = 1L, quotients = 1L, ...)quot(x, lag = 1L, quotients = 1L, ...)
x |
a numeric vector or matrix containing the values to be used for calculating the quotients. |
lag |
an integer indicating which lag to use. |
quotients |
an integer indicating the order of the quotient. |
... |
further arguments to be passed to or from methods. |
NA()'s propagate.
if x is a vector of length n and quotients = 1,
then the computed result is equal to the successive quotients
x[(1+lag):n] / x[1:(n-lag)].
If quotients is larger than one this algorithm is applied recursively
to x. Note that the returned value is a vector which is shorter than
x.
If x is a matrix then the division operations are carried out on each
column separately.
Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language. Wadsworth & Brooks/Cole.
Other vector.window:
midx(),
moveAvg()
quot(1:10, 2) quot(1:10, 2, 2) x <- cumprod(cumprod(1:10)) quot(x, lag = 2) quot(x, quotients = 2)quot(1:10, 2) quot(1:10, 2, 2) x <- cumprod(cumprod(1:10)) quot(x, lag = 2) quot(x, quotients = 2)
Randomly assigns the elements of a vector x into groups with
predefined sizes given by groupSizes. The grouping is performed
without replacement and each element is assigned to exactly one group.
randGroupSplit(x, groupSizes)randGroupSplit(x, groupSizes)
x |
a vector containing the elements to be split into groups. |
groupSizes |
an integer vector specifying the sizes of the groups.
The sum of |
This function is useful for random group assignments, for example in
teaching settings, simulations, or experimental designs where groups
of unequal sizes are required. It uses sample(), so results
can be made reproducible with set.seed().
a list of vectors, where each element corresponds to one group.
The length of the list equals length(groupSizes).
Other combinatorics:
combN(),
combPairs(),
combSet(),
pairApply(),
permn(),
sampleX()
# Split letters into 3 groups of sizes 4, 3, and 5 set.seed(123) randGroupSplit(LETTERS[1:12], groupSizes = c(4, 3, 5)) # named groups randGroupSplit(LETTERS[1:7], groupSizes = c(treat = 4, ctrl = 3))# Split letters into 3 groups of sizes 4, 3, and 5 set.seed(123) randGroupSplit(LETTERS[1:12], groupSizes = c(4, 3, 5)) # named groups randGroupSplit(LETTERS[1:7], groupSizes = c(treat = 4, ctrl = 3))
Returns the elements of x from the first occurrence of rng[1] up to an
occurrence of rng[2]. The two operators differ in which occurrence of
the end value terminates the range, analogous to lazy and greedy
quantifiers in regular expressions:
x %:% rng x %::% rngx %:% rng x %::% rng
x |
a vector. |
rng |
a vector of length 2: |
%:% (lazy): up to the first occurrence of rng[2].
%::% (greedy): up to the last occurrence of rng[2].
a subset of x, from the first occurrence of rng[1] to the
first (%:%) or last (%::%) occurrence of rng[2].
Other data.interval:
between-operators,
intervals
letters %:% c("c", "g") x <- c("a", "b", "c", "d", "c", "e", "f", "c") x %:% c("c", "e") x %::% c("c", "c") # greedy: up to the last "c" # select a column range by name colnames(mtcars) %:% c("hp", "vs")letters %:% c("c", "g") x <- c("a", "b", "c", "d", "c", "e", "f", "c") x %:% c("c", "e") x %::% c("c", "c") # greedy: up to the last "c" # select a column range by name colnames(mtcars) %:% c("hp", "vs")
Computes ranks for vectors or multiple inputs using a fast implementation
based on data.table::frankv. Supports additional tie-handling
methods such as "dense" and multi-column ranking via ....
rankX( ..., decreasing = FALSE, na.last = TRUE, ties.method = c("average", "first", "last", "random", "max", "min", "dense") )rankX( ..., decreasing = FALSE, na.last = TRUE, ties.method = c("average", "first", "last", "random", "max", "min", "dense") )
... |
one or more vectors to be ranked. If multiple vectors are
provided, they are ranked lexicographically (like |
decreasing |
logical; if |
na.last |
logical or |
ties.method |
character string specifying how ties are handled. One of:
|
This function is a fast alternative to rank(), powered by
data.table::frankv. It extends base functionality by:
Supporting dense ranking (ties.method = "dense")
Allowing multiple input vectors for lexicographic ranking
Providing improved performance for large datasets
When multiple inputs are supplied, ranking is performed jointly, similar to:
order(x1, x2, ...)
an integer or numeric vector of ranks with the same length as the input.
Other math.transform:
linScale(),
logit(),
percentRank(),
winsorize()
x <- c(10, 20, 20, 30) # Basic ranking rankX(x) # Dense ranking rankX(x, ties.method = "dense") # Descending order rankX(x, decreasing = TRUE) # Handling NA values x2 <- c(3, NA, 1, 2) rankX(x2, na.last = "keep") # Multi-column ranking a <- c(1, 1, 2, 2) b <- c(2, 1, 2, 1) rankX(a, b)x <- c(10, 20, 20, 30) # Basic ranking rankX(x) # Dense ranking rankX(x, ties.method = "dense") # Descending order rankX(x, decreasing = TRUE) # Handling NA values x2 <- c(3, NA, 1, 2) rankX(x2, na.last = "keep") # Multi-column ranking a <- c(1, 1, 2, 2) b <- c(2, 1, 2, 1) rankX(a, b)
Generates beta-distributed random values using predefined distributional shapes and transforms them to a specified interval.
rBetaShape( n, shape = c("norm", "left", "right", "unif", "u", "j", "inv-j"), bounds = c(0, 1) )rBetaShape( n, shape = c("norm", "left", "right", "unif", "u", "j", "inv-j"), bounds = c(0, 1) )
n |
non-negative integer giving the number of values to generate. |
shape |
distributional shape: either one of the predefined names
listed under Details, or a numeric vector of length 2 giving
|
bounds |
numeric vector containing the lower and upper bound. |
The following predefined shapes and beta parameters are available:
| Shape | shape1 | shape2 | Description |
"norm" |
5.0 | 5.0 | symmetric and bell-shaped |
"left" |
5.0 | 2.0 | left-skewed with values concentrated near the upper bound |
"right" |
2.0 | 5.0 | right-skewed with values concentrated near the lower bound |
"unif" |
1.0 | 1.0 | uniform |
"u" |
0.5 | 0.5 | U-shaped with values concentrated near both bounds |
"j" |
2.0 | 0.5 | J-shaped with values concentrated near the upper bound |
"inv-j" |
0.5 | 2.0 | inverse J-shaped with values concentrated near the lower bound |
Note that "left" and "right" name the direction of the skew, i.e.
of the long tail, so "right" places the bulk of the values near the
lower bound. This is the standard convention, but it is the opposite of
what the names suggest at first reading - and unrelated to the meaning
of "left"/"right" in the sides argument of the interval functions,
where they name the side carrying the finite bound.
The "norm" shape is symmetric and bell-shaped but is not a normal
distribution. Unlike the normal distribution, all generated values are
bounded.
Values from the standard beta distribution on the interval
are transformed to the interval specified by bounds as
where and are the lower and upper bounds, respectively.
a numeric vector of length n with values within bounds.
The values are drawn with rbeta() and therefore depend on the
state of R's global random number generator. No seed is set internally;
call set.seed() beforehand, or wrap the call in
withSeed(), for reproducible results.
Other random.numbers:
rSum21()
set.seed(42) x <- rBetaShape( 1000, shape = "right", bounds = c(10, 90) ) summary(x) range(x) # shape parameters can also be given directly rBetaShape(5, shape = c(3, 1.5), bounds = c(0, 100))set.seed(42) x <- rBetaShape( 1000, shape = "right", bounds = c(10, 90) ) summary(x) range(x) # shape parameters can also be given directly rBetaShape(5, shape = c(3, 1.5), bounds = c(0, 100))
Reads the variable descriptions out of the \describe section of a
documented dataset and returns them as a named character vector, the names
being the variable names. This turns documentation that already exists into
labels usable in tables, plots and codebooks, instead of maintaining the
same descriptions a second time in the code.
rdLabels(dataName, package)rdLabels(dataName, package)
dataName |
character string, the name of the dataset. |
package |
character string, the name of the package holding the dataset. |
The Rd database is read with tools::Rd_db() and searched recursively for
the first \describe section, from which all
\item{var}{description} entries are taken. Only that first
section is read: on a page documenting more than one dataset, the labels of
the first one are returned.
Descriptions are returned as written in the Rd file, with whitespace and
line breaks collapsed to single spaces. Rd markup inside a description, such
as \code{} or \eqn{}, contributes its content without the surrounding
command.
The package must be installed, as the documentation is read from the installed Rd database rather than from the sources.
a named character vector of variable descriptions, the names being the variable names.
Other pkg.funinfo:
auditNames(),
funArgs(),
funCalls(),
funKeywords(),
funList(),
rdTitle()
# the labels of a documented dataset, taken from the \describe # section of its help page rdLabels("Pizza", "bedrock")# the labels of a documented dataset, taken from the \describe # section of its help page rdLabels("Pizza", "bedrock")
Searches all ‘.Rd’ files in a package's ‘man/’ directory for a
given topic (matched against \\alias entries) and returns its
\\title string.
rdTitle(topic, man = "man")rdTitle(topic, man = "man")
topic |
a single character string giving the topic (function name or alias) to look up. |
man |
a single character string giving the path to the directory
containing ‘.Rd’ files. Defaults to |
a single character string with the title, trimmed of leading and
trailing whitespace. Stops with an error if topic is not found.
Other pkg.funinfo:
auditNames(),
funArgs(),
funCalls(),
funKeywords(),
funList(),
rdLabels()
# a minimal man/ directory to search in man <- file.path(tempdir(), "man") dir.create(man, showWarnings = FALSE) writeLines(c("\\\\name{foo}", "\\\\alias{foo}", "\\\\alias{bar}", "\\\\title{A Minimal Help Page}", "\\\\description{Nothing to see here.}"), file.path(man, "foo.Rd")) rdTitle("foo", man = man) rdTitle("bar", man = man) # aliases are matched as well rdTitle("nothing", man = man) # NA unlink(man, recursive = TRUE)# a minimal man/ directory to search in man <- file.path(tempdir(), "man") dir.create(man, showWarnings = FALSE) writeLines(c("\\\\name{foo}", "\\\\alias{foo}", "\\\\alias{bar}", "\\\\title{A Minimal Help Page}", "\\\\description{Nothing to see here.}"), file.path(man, "foo.Rd")) rdTitle("foo", man = man) rdTitle("bar", man = man) # aliases are matched as well rdTitle("nothing", man = man) # NA unlink(man, recursive = TRUE)
Downloads and loads a dataset from predefined course servers or a user-defined URL.
readCourseData(name, url = NULL, header = TRUE, sep = ";", ...)readCourseData(name, url = NULL, header = TRUE, sep = ";", ...)
name |
character string. File name including extension (e.g. |
url |
optional character string. Base URL where the file is located.
If |
header |
logical. Whether the file contains a header row. Passed to |
sep |
character. Field separator used in the file. Default is |
... |
additional arguments passed to the underlying import functions
such as |
If no url is provided, the function searches for the file in
the following locations (see https://github.com/AndriSignorell/Teaching):
https://raw.githubusercontent.com/AndriSignorell/Teaching/main/book/
https://raw.githubusercontent.com/AndriSignorell/Teaching/main/data/
The first location where the file exists is used.
File type handling:
.xls, .xlsx: loaded via openDataObject()
other files: loaded via read.table()
a data frame or object returned by the respective import function:
for text files: a data.frame.
for Excel files: an object returned by openDataObject().
Other datasets:
Cards,
Pizza,
Roulette,
Tarot
# the files are fetched from a remote repository, so the examples # need an internet connection and fail gracefully without one # load from the default repositories try(readCourseData("fullmoon.xlsx")) # load from a custom URL try(readCourseData("mydata.csv", url = "https://example.com/data/"))# the files are fetched from a remote repository, so the examples # need an internet connection and fail gracefully without one # load from the default repositories try(readCourseData("fullmoon.xlsx")) # load from a custom URL try(readCourseData("mydata.csv", url = "https://example.com/data/"))
Reads a file from the Downloads directory and returns it as a data frame. The file type is automatically detected from the extension.
readDownload(file, ..., output = c("data.frame", "tibble"))readDownload(file, ..., output = c("data.frame", "tibble"))
file |
character string specifying the name of the file. |
... |
additional arguments passed to the underlying read
function, e.g. |
output |
character, either |
This is a convenience wrapper combining findDownload() with
common file readers:
Excel files (.xls, .xlsx) via
readxl::read_excel
CSV files via readr::read_csv
TSV files via readr::read_tsv
Text files (.txt) via readr::read_delim,
which guesses the delimiter from the file content
For the readr-based formats the column specification message is
suppressed by default; supply show_col_types = TRUE to restore
it. By default, the result is converted to a base R data.frame.
a data.frame or a tibble, according to output.
findDownload(),
toBaseR(), readxl::read_excel(),
readr::read_csv()
Other file.io:
parseSasDatalines(),
pdfManual(),
peekFile()
## Not run: # cannot be run automatically: reads the personal Downloads # directory of the user, where no such files exist # read an Excel file readDownload("data.xlsx") # read a CSV file readDownload("data.csv") # keep the tibble output readDownload("data.csv", output = "tibble") ## End(Not run)## Not run: # cannot be run automatically: reads the personal Downloads # directory of the user, where no such files exist # read an Excel file readDownload("data.xlsx") # read a CSV file readDownload("data.csv") # keep the tibble output readDownload("data.csv", output = "tibble") ## End(Not run)
Combining or rearranging a factor can be tedious if it has many levels.
recodeX() supports this step by accepting a direct definition of new
levels by enumerating old levelnames as argument and adding an
"elseLevel" option. If new levels are given as integer values they
will be translated in the according levels.
recodeX( x, ..., keep = NULL, elseLevel = NA, ref = NULL, useEmpty = FALSE, num = FALSE )recodeX( x, ..., keep = NULL, elseLevel = NA, ref = NULL, useEmpty = FALSE, num = FALSE )
x |
the factor whose levels are to be altered. If x is
|
... |
the old levels (combined by |
keep |
vector of levels that should be left untouched. |
elseLevel |
the value for levels, which are not matched by newlevel
list. If this is set to |
ref |
the reference level, typically a string. |
useEmpty |
logical. Defines how a new level, which can't be found in
x, should be handled. Should it be left in the level's list or be dropped?
The default is |
num |
logical. If set to |
the factor having the new levels applied.
if x was a
character vector, the result will also be character.
factor(), levels(), relevel(),
reorder()
There's another solution for this problem in the
package car.
Other data.recode:
asBinary(),
combLevels(),
dummy(),
mReplace(),
nf(),
revCode(),
stringsAsFactors()
set.seed(1984) x <- factor(sample(1:15, 20, replace=TRUE)) levels(x) <- paste("old", levels(x), sep="_") y <- recodeX(x, "new_1" = c("old_1","old_4","old_5"), "new_2" = c("old_6","old_10","old_11"), "new_3" = c("old_12","old_13"), elseLevel = "other") data.frame(x=x, y=y) # Coding NAs, NA is recoded to new_1 x[5:6] <- NA x <- x[1:7] data.frame( x, RecodeNA = recodeX(x, "new_1" = c("old_4","old_8", NA), elseLevel = "other"), # NAs remain unaffected, unless specified to be processed NoRecodeNA = recodeX(x, "new_1" = c("old_4","old_8"), elseLevel = "other") ) # keep some levels, collapse others and reset the reference level ff <- factor(c("apple","pear","banana","kiwi", "mango","peach","grape","plum")) recodeX(ff, stone=c("peach", "plum"), keep=c("apple","banana"), elseLevel = "other", ref="stone") x <- factor(letters[1:6]) z1 <- recodeX(x, AB=c("a","b"), CD=c("c","d"), elseLevel="none of these") z2 <- recodeX(x, AB=c("a","b"), CD=c("c","d"), elseLevel=NA) z3 <- recodeX(x, AB=c("a","b"), CD=c("c","d"), elseLevel=NULL) z4 <- recodeX(x, AB=c("a","b"), GH=c("g","h"), elseLevel=NA, useEmpty=TRUE) z5 <- recodeX(x, AB=c("a","b"), GH=c("g","h"), elseLevel=NA, useEmpty=FALSE) data.frame(z1, z2, z3, z4, z5) lapply(data.frame(z1, z2, z3, z4, z5), levels) # empty level GH exists in z4... table(z4, useNA="ifany") # and is dropped in z5 table(z5, useNA="ifany") # use integers to define the groups to collapse set.seed(1972) (likert <- factor(sample(1:10, size=15, replace=TRUE), levels=1:10, labels=gettextf("(%s)", 1:10))) recodeX(likert, det=1:6, pas=7:8, pro=9:10) # or directly turned to numeric recodeX(likert, "1"=1:6, "2"=7:8, "5"=9:10, num=TRUE)set.seed(1984) x <- factor(sample(1:15, 20, replace=TRUE)) levels(x) <- paste("old", levels(x), sep="_") y <- recodeX(x, "new_1" = c("old_1","old_4","old_5"), "new_2" = c("old_6","old_10","old_11"), "new_3" = c("old_12","old_13"), elseLevel = "other") data.frame(x=x, y=y) # Coding NAs, NA is recoded to new_1 x[5:6] <- NA x <- x[1:7] data.frame( x, RecodeNA = recodeX(x, "new_1" = c("old_4","old_8", NA), elseLevel = "other"), # NAs remain unaffected, unless specified to be processed NoRecodeNA = recodeX(x, "new_1" = c("old_4","old_8"), elseLevel = "other") ) # keep some levels, collapse others and reset the reference level ff <- factor(c("apple","pear","banana","kiwi", "mango","peach","grape","plum")) recodeX(ff, stone=c("peach", "plum"), keep=c("apple","banana"), elseLevel = "other", ref="stone") x <- factor(letters[1:6]) z1 <- recodeX(x, AB=c("a","b"), CD=c("c","d"), elseLevel="none of these") z2 <- recodeX(x, AB=c("a","b"), CD=c("c","d"), elseLevel=NA) z3 <- recodeX(x, AB=c("a","b"), CD=c("c","d"), elseLevel=NULL) z4 <- recodeX(x, AB=c("a","b"), GH=c("g","h"), elseLevel=NA, useEmpty=TRUE) z5 <- recodeX(x, AB=c("a","b"), GH=c("g","h"), elseLevel=NA, useEmpty=FALSE) data.frame(z1, z2, z3, z4, z5) lapply(data.frame(z1, z2, z3, z4, z5), levels) # empty level GH exists in z4... table(z4, useNA="ifany") # and is dropped in z5 table(z5, useNA="ifany") # use integers to define the groups to collapse set.seed(1972) (likert <- factor(sample(1:10, size=15, replace=TRUE), levels=1:10, labels=gettextf("(%s)", 1:10))) recodeX(likert, det=1:6, pas=7:8, pro=9:10) # or directly turned to numeric recodeX(likert, "1"=1:6, "2"=7:8, "5"=9:10, num=TRUE)
This function recycles all supplied elements to the maximal dimension.
recycle(..., maxDim = NULL, strict = FALSE)recycle(..., maxDim = NULL, strict = FALSE)
... |
a number of vectors of elements. |
maxDim |
defines the maximal dimension, if set to |
strict |
logical, if |
If maxDim is smaller than the length of an element, that element
is truncated to the first maxDim values. Zero-length elements are
recycled to NA vectors of length maxDim. Both situations
are rejected when strict = TRUE.
a list of the supplied elementsattr(,"maxdim") contains
the maximal dimension of the recycled list.
Other pkg.args:
callIf(),
extractArgs(),
getDotsArg(),
mergeArgs()
recycle(x=1:5, y=1, s=letters[1:2]) z <- recycle(x=letters[1:5], n=2:3, sep=c("-"," ")) sapply(1:attr(z, "maxdim"), function(i) paste(rep(z$x[i], times=z$n[i]), collapse=z$sep[i]))recycle(x=1:5, y=1, s=letters[1:2]) z <- recycle(x=letters[1:5], n=2:3, sep=c("-"," ")) sapply(1:attr(z, "maxdim"), function(i) paste(rep(z$x[i], times=z$n[i]), collapse=z$sep[i]))
Renames selected elements of a named object by specifying old-to-new name
mappings. Works on any R object that supports names(),
including vectors, lists, data frames, and matrices. For matrix-like
objects, rownames and colnames can be targeted via the
which argument.
renameX( x, ..., on = c("names", "rownames", "colnames"), useGsub = FALSE, fixed = TRUE, warn = TRUE )renameX( x, ..., on = c("names", "rownames", "colnames"), useGsub = FALSE, fixed = TRUE, warn = TRUE )
x |
a named object. Any type that supports |
... |
name mappings of the form |
on |
character scalar specifying which names to operate on.
One of |
useGsub |
logical scalar. If |
fixed |
logical scalar. Passed to |
warn |
logical scalar. If |
The function supports three modes:
useGsub = FALSE, default)Names are matched exactly via match(). Each element of
... must be a named scalar character string of the form
old = "new". Unmatched old names trigger a warning when
warn = TRUE.
useGsub = TRUE)Each mapping is treated as a gsub() substitution applied
in sequence to all current names. The left-hand side is the
pattern, the right-hand side is the replacement. The fixed
argument is forwarded to gsub().
If a single function is passed in ..., it is applied to all
current names. Useful for bulk transformations such as
toupper, tolower, or make.names.
When ... contains unnamed character elements, the names are assigned
positionally: the first element replaces names(x)[1], the second
names(x)[2], and so on.
the object x with updated names; all other attributes are
preserved.
Other label.attrs:
label(),
setAttr-removeAttr-keepAttr,
setNamesX()
x <- c(a = 1, b = 2, c = 3) # Exact mode: rename by old = "new" pairs renameX(x, a = "alpha", c = "gamma") # Positional mode: replaces names(x)[1:2] renameX(x, "alpha", "beta") # Function mode: apply a function to all names renameX(x, toupper) renameX(x, tolower) # Data frame columns d <- data.frame(foo = 1:3, bar = 4:6) renameX(d, foo = "x", bar = "y") # Pattern mode: strip a common prefix y <- c(v_mean = 1, v_sd = 2, v_n = 3) renameX(y, v_ = "", useGsub = TRUE) # Pattern mode with regex (fixed = FALSE) renameX(y, `^v_` = "", useGsub = TRUE, fixed = FALSE) # Matrix: rename colnames selectively m <- matrix(1:6, nrow = 2, dimnames = list(c("row_a", "row_b"), c("col_x", "col_y", "col_z"))) renameX(m, col_x = "alpha", on = "colnames") # Matrix: uppercase all rownames via function mode renameX(m, toupper, on = "rownames") # Matrix: rename rownames via gsub renameX(m, `row_` = "", useGsub = TRUE, fixed = FALSE, on = "rownames")x <- c(a = 1, b = 2, c = 3) # Exact mode: rename by old = "new" pairs renameX(x, a = "alpha", c = "gamma") # Positional mode: replaces names(x)[1:2] renameX(x, "alpha", "beta") # Function mode: apply a function to all names renameX(x, toupper) renameX(x, tolower) # Data frame columns d <- data.frame(foo = 1:3, bar = 4:6) renameX(d, foo = "x", bar = "y") # Pattern mode: strip a common prefix y <- c(v_mean = 1, v_sd = 2, v_n = 3) renameX(y, v_ = "", useGsub = TRUE) # Pattern mode with regex (fixed = FALSE) renameX(y, `^v_` = "", useGsub = TRUE, fixed = FALSE) # Matrix: rename colnames selectively m <- matrix(1:6, nrow = 2, dimnames = list(c("row_a", "row_b"), c("col_x", "col_y", "col_z"))) renameX(m, col_x = "alpha", on = "colnames") # Matrix: uppercase all rownames via function mode renameX(m, toupper, on = "rownames") # Matrix: rename rownames via gsub renameX(m, `row_` = "", useGsub = TRUE, fixed = FALSE, on = "rownames")
Brings a two-way classification into one canonical shape, no matter whether it arrives as a ready-made contingency table or as two classification variables. The function validates the counts, drops the incomplete observations and reports the table together with its dimensions, so that association measures, tests of independence and agreement statistics can share one entry point instead of each repeating the same preparation.
resolveContingency( x, y = NULL, square = FALSE, integerCounts = TRUE, dataName = NULL )resolveContingency( x, y = NULL, square = FALSE, integerCounts = TRUE, dataName = NULL )
x |
a contingency table or matrix of counts, or a factor or vector of classifications. |
y |
an optional factor or vector of classifications, of the same length
as |
square |
logical, whether a square contingency table is required,
defaults to |
integerCounts |
logical, whether non-integer counts should be reported
with a warning, defaults to |
dataName |
optional character string used as the |
Any two-dimensional object is taken as a contingency table and used as it
is, which covers a matrix as well as a table() or xtabs() object; a data
frame of counts is coerced with as.matrix(). Its entries must be numeric,
non-negative and finite; non-integer counts are reported with a warning
unless integerCounts is set to FALSE, as they occur legitimately in
weighted or expected tables. An array of any other number of dimensions is
an error, rather than being flattened into a classification variable.
Two classification variables are cross-tabulated instead. Observations missing in either variable are dropped, both variables are then coerced to factors, which drops the levels that no longer occur, and at least two levels must remain on each side.
Whichever way the table arrives, it must have at least two rows and two columns: a one-way table carries no association to measure and is rejected rather than passed on to a caller that cannot use it.
square is meant for the statistics that compare two ratings of the same
items, such as the tests of marginal homogeneity or the agreement measures.
For two classification variables it tabulates both over the union of their
observed levels (those of x first), so the axes carry the same categories
in the same order and a category used by only one rating becomes a row or
column of zeros: x using A, B and y using B, C give a 3 x 3 table over
A, B, C instead of rows A, B against columns B, C. For a ready-made table it
only guarantees as many columns as rows: whether the two axes really carry
the same categories cannot be checked on a table that may have no
dimnames at all, and remains the responsibility of the caller.
a list containing:
the contingency table.
the total sample size, the sum of all counts.
integer, the number of rows.
integer, the number of columns.
character description of the input, for use as the
data.name of an htest object.
table(), resolveGroups(), resolveFormula()
Other data.resolve:
resolveFormula(),
resolveGroups()
# from an existing contingency table tab <- matrix(c(10, 5, 3, 12), nrow = 2, dimnames = list(c("A", "B"), c("yes", "no"))) str(resolveContingency(tab)) # from two classification variables set.seed(1) x <- sample(c("low", "high"), 100, replace = TRUE) y <- sample(c("yes", "no"), 100, replace = TRUE) resolveContingency(x, y)$table # a caller passes the name it sees at its own call site myTest <- function(x, y) { r <- resolveContingency(x, y, dataName = paste(deparse1(substitute(x)), "and", deparse1(substitute(y)))) r$dataName } myTest(x, y) ## [1] "x and y"# from an existing contingency table tab <- matrix(c(10, 5, 3, 12), nrow = 2, dimnames = list(c("A", "B"), c("yes", "no"))) str(resolveContingency(tab)) # from two classification variables set.seed(1) x <- sample(c("low", "high"), 100, replace = TRUE) y <- sample(c("yes", "no"), 100, replace = TRUE) resolveContingency(x, y)$table # a caller passes the name it sees at its own call site myTest <- function(x, y) { r <- resolveContingency(x, y, dataName = paste(deparse1(substitute(x)), "and", deparse1(substitute(y)))) r$dataName } myTest(x, y) ## [1] "x and y"
Parses a model formula, builds the model frame and classifies the resulting
design into one of seven dependency structures. The pieces of the design are
returned under a fixed set of names, so that every function offering a
formula interface can share one entry point instead of re-implementing the
parsing, the subset handling and the distinction between a grouping
factor, a numeric predictor and a blocking variable.
resolveFormulaFromCall() is the entry point for a function offering a
formula interface: called from its body, it forwards the caller's
formula, data and subset to resolveFormula() exactly as they were
written, so that subset keeps its base R semantics (see Details).
resolveFormula( formula, data, subset, na.action = na.pass, allowed = c("one-sample", "two-sample-independent", "two-sample-dependent", "n-sample-independent", "n-sample-dependent", "numeric-numeric", "regression") ) resolveFormulaFromCall(allowed, na.action = na.pass)resolveFormula( formula, data, subset, na.action = na.pass, allowed = c("one-sample", "two-sample-independent", "two-sample-dependent", "n-sample-independent", "n-sample-dependent", "numeric-numeric", "regression") ) resolveFormulaFromCall(allowed, na.action = na.pass)
formula |
a two-sided model formula. Supported forms are:
|
data |
an optional data frame containing the variables in |
subset |
an optional expression indicating the observations to use,
evaluated in |
na.action |
a function specifying how missing values are handled,
defaults to |
allowed |
a character vector restricting which design types are
accepted, any combination of |
Design types
one-sampley ~ 1, as in the one-sample t-test or the
one-sample Wilcoxon test.
two-sample-independenty ~ g with two groups, as in the
two-sample t-test or the Wilcoxon rank-sum test.
two-sample-dependentPair(x, y) ~ 1, as in the paired t-test
or the Wilcoxon signed-rank test.
n-sample-independenty ~ g with more than two groups, as in
the analysis of variance or the Kruskal-Wallis test.
n-sample-dependenty ~ trt | block, as in a repeated-measures
analysis of variance or the Friedman test.
numeric-numericy ~ x with a numeric right-hand side, as in
correlation or simple regression.
regressiona general regression formula with one or more predictors.
Type detection
The type follows from the shape of the formula and from the class of the
right-hand side variable, not from allowed. allowed only decides
whether the detected type is accepted, with four exceptions worth knowing.
A grouping factor carrying a single level is reported as
one-sample if that type is allowed.
A two-group design is reported as n-sample-independent if
"two-sample-independent" is not among the allowed types. Together
with the previous rule this lets a caller that treats every group count
alike allow one type only.
allowed = "regression" on its own forces the regression type
for every formula, including y ~ 1 and y ~ g, with the exception
of the blocked syntax y ~ trt | block, which is always
n-sample-dependent and therefore an error then. This is the entry
point for model-fitting callers, which interpret the right-hand side
themselves. Duplicates in allowed are ignored, so
c("regression", "regression") behaves the same.
Otherwise regression is reported only for more than one
right-hand side variable. With allowed containing both "regression"
and "numeric-numeric", y ~ x is therefore numeric-numeric while
y ~ x1 + x2 is regression.
Cells of several grouping variables
A right-hand side consisting of a single interaction term, y ~ a:b (or
y ~ a:b:c), is the explicit request for the cells of these variables.
They are combined into one grouping factor via interaction(), with
levels such as "OJ:0.5"; numeric components are treated as categorical.
The design is then classified like y ~ g, by the number of non-empty
cells.
Unlike boxplot(), y ~ a + b is not read as cells: additive terms are
not an interaction, as in lm(). Such a formula, like y ~ a * b, is
regression if that type is allowed, and an error otherwise. If
"regression" is allowed, it also takes precedence over the cell reading
of y ~ a:b, which a model-fitting caller interprets as an interaction
term.
The distinction rests on the terms of the formula: the model frame
holds the variables a and b in both cases and cannot tell the two
apart.
offset() is only accepted for the regression design and an error
otherwise: an offset column is part of the model frame without being a
term, and would pass for a grouping variable or a numeric predictor.
Field naming contract (binding across all types)
response is present for every type and always holds the
left-hand side of the formula. It is the one field a caller can rely on
without branching on type.
x is an alias of response for the types that are conventionally
described in terms of a sample rather than a model (one-sample,
two-sample-independent, n-sample-independent, numeric-numeric).
The exception is two-sample-dependent: there response is the whole
Pair() matrix, while x and y are its first and second column.
group is reserved for a categorical, factor-coercible variable of
length n (the full sample) that splits the response into groups. It
is never pre-split and never used for a continuous variable. x and
group have an identical shape for two-sample-independent and for
n-sample-independent, so that a caller can use
split(r$x, r$group) uniformly, without branching on the number of
groups. For y ~ a:b, group holds the combined cell factor.
predictor is used for a continuous, numeric right-hand side
variable (numeric-numeric), never group.
treatment is used for the explanatory variable of a blocked
design (n-sample-dependent), as distinct from block, the
stratification factor. Neither is ever called group.
y, where present, is a convenience field only, holding the second
group of a two-sample design or the second paired vector. It is never
needed for correct use: x and group (or x and predictor, or
treatment and block) are always sufficient and are the canonical
access path.
rows is present for every type and holds the positions of the
retained observations in the original data, after subset and after
na.action. It is the handle for synchronising an external vector
(an ordering variable, weights) with the model frame:
z <- z[r$rows]. It is NULL in the rare case where the row names of
the model frame cannot be matched back, e.g. when a numeric subset
selects a row twice.
terms is returned for the regression type. Build the design
matrix from it, model.matrix(r$terms, r$mf), never from the original
formula: the columns of a model frame are named after the deparsed
expressions ("log(x)"), so re-evaluating the formula against the
model frame fails for every transformed term.
Missing values
Missing values are left to na.action and are not touched otherwise, so
with the default na.pass() they reach the caller untouched. The one
exception is the grouping factor of an independent design, where empty and
missing levels are dropped before the groups are counted. A grouping
variable that is missing throughout leaves no level at all and is an error.
A cell of y ~ a:b is missing as soon as one of its components is.
Rows removed by na.action are recorded in attr(r$mf, "na.action"), but
those indices are relative to the already subsetted frame. To align an
external vector with the model frame use rows, which accounts for
subset and na.action at once.
subset handling
subset is evaluated as in base R: it is taken unevaluated, like
lm() does, by handing this function's own call on to model.frame(),
which evaluates the expression in data, with environment(formula) as
the enclosure. resolveFormula(y ~ g, df, subset = g == "A") therefore
works exactly like boxplot(y ~ g, df, subset = g == "A"), and a quoted
expression fails in both.
A wrapper function forwards its arguments the same way base R does (see
boxplot.formula()): it rebuilds its own call and evaluates it in its
caller's frame, so that subset reaches resolveFormula() unevaluated.
resolveFormulaFromCall() does exactly this and is the entry point to use
in a formula method:
myFun <- function(formula, data, subset, na.action = na.omit, ...) {
r <- resolveFormulaFromCall(
allowed = c("two-sample-independent", "n-sample-independent"),
na.action = na.action)
...
}
Passing a captured expression on by value
(resolveFormula(formula, data, subset = substitute(subset))) does not
work, just as it does not for model.frame() itself.
Return components by type
Every return value starts with type, mf, rows and response, in that
order, followed by the design-specific components below, and ends with
dataName:
one-samplex
two-sample-independentx, group, y (convenience: the
second group)
two-sample-dependentx, y
n-sample-independentx, group
n-sample-dependenttreatment, block
numeric-numericx, predictor
regressionterms
resolveFormulaFromCall()
Rebuilds the call of the function it is called from - via match.call()
against that function's definition, which works for an S3 method as well
keeps its formula, data and subset arguments, and evaluates
resolveFormula() with them in the frame the calling function was called
from. This is the forwarding pattern of boxplot.formula() and lm(),
written once:
plotBox.formula <- function(formula, data, subset, na.action = na.omit, ...) {
r <- bedrock::resolveFormulaFromCall(
allowed = c("two-sample-independent", "n-sample-independent"),
na.action = na.action)
...
}
allowed is passed on as given (omitted: all types). na.action should
be the calling function's own na.action value; it is always passed on,
so that the caller's default (typically na.omit()) applies rather than
the na.pass() default of resolveFormula().
Requirements for the calling function: its arguments must be named
formula, data and subset, and resolveFormulaFromCall() must be
called directly in its body, not from a nested helper function, since the
call is looked up one frame up.
a named list containing at least:
character, one of the design types listed above.
the model.frame() the design was read from.
integer, the positions of the retained observations in the
original data, or NULL if they cannot be determined.
the left-hand side of the formula.
character, the deparsed formula, for use as the
data.name of an htest object.
plus the design-specific components described under Details.
model.frame(), Pair(), resolveGroups()
Other data.resolve:
resolveContingency(),
resolveGroups()
set.seed(1) df <- data.frame( y = rnorm(30, 50, 10), g2 = rep(c("A", "B"), 15), g3 = rep(c("A", "B", "C"), 10), trt = rep(c("T1", "T2", "T3"), 10), blk = rep(1:10, 3) ) # one-sample resolveFormula(y ~ 1, data = df)$type ## [1] "one-sample" # two-sample independent: x and group have full length, the same shape # as for more than two groups r2 <- resolveFormula(y ~ g2, data = df, allowed = c("two-sample-independent", "n-sample-independent")) r2$type ## [1] "two-sample-independent" length(r2$x) == length(r2$group) ## [1] TRUE # n-sample independent resolveFormula(y ~ g3, data = df, allowed = "n-sample-independent")$type ## [1] "n-sample-independent" # cells of two grouping variables: a:b, not a + b r3 <- resolveFormula(y ~ g2:g3, data = df, allowed = "n-sample-independent") levels(r3$group) ## [1] "A:A" "B:A" "A:B" "B:B" "A:C" "B:C" try(resolveFormula(y ~ g2 + g3, data = df, allowed = "n-sample-independent")) # two-sample dependent (paired) df2 <- data.frame(pre = rnorm(15, 50, 10), post = rnorm(15, 55, 10)) resolveFormula(Pair(pre, post) ~ 1, data = df2, allowed = c("one-sample", "two-sample-dependent"))$type ## [1] "two-sample-dependent" # n-sample dependent (blocked): treatment, not group r4 <- resolveFormula(y ~ trt | blk, data = df, allowed = "n-sample-dependent") names(r4) ## [1] "type" "mf" "rows" "response" "treatment" "block" "dataName" # numeric-numeric: predictor, not group df3 <- data.frame(y = rnorm(20), x = rnorm(20)) r5 <- resolveFormula(y ~ x, data = df3, allowed = "numeric-numeric") is.numeric(r5$predictor) ## [1] TRUE # regression: build the design matrix from 'terms', not from the formula r6 <- resolveFormula(y ~ log(abs(x)) + I(x^2), data = df3, allowed = "regression") colnames(model.matrix(r6$terms, r6$mf)) # subset, as in base R resolveFormula(y ~ g3, data = df, subset = g3 != "C", allowed = "two-sample-independent")$type ## [1] "two-sample-independent"set.seed(1) df <- data.frame( y = rnorm(30, 50, 10), g2 = rep(c("A", "B"), 15), g3 = rep(c("A", "B", "C"), 10), trt = rep(c("T1", "T2", "T3"), 10), blk = rep(1:10, 3) ) # one-sample resolveFormula(y ~ 1, data = df)$type ## [1] "one-sample" # two-sample independent: x and group have full length, the same shape # as for more than two groups r2 <- resolveFormula(y ~ g2, data = df, allowed = c("two-sample-independent", "n-sample-independent")) r2$type ## [1] "two-sample-independent" length(r2$x) == length(r2$group) ## [1] TRUE # n-sample independent resolveFormula(y ~ g3, data = df, allowed = "n-sample-independent")$type ## [1] "n-sample-independent" # cells of two grouping variables: a:b, not a + b r3 <- resolveFormula(y ~ g2:g3, data = df, allowed = "n-sample-independent") levels(r3$group) ## [1] "A:A" "B:A" "A:B" "B:B" "A:C" "B:C" try(resolveFormula(y ~ g2 + g3, data = df, allowed = "n-sample-independent")) # two-sample dependent (paired) df2 <- data.frame(pre = rnorm(15, 50, 10), post = rnorm(15, 55, 10)) resolveFormula(Pair(pre, post) ~ 1, data = df2, allowed = c("one-sample", "two-sample-dependent"))$type ## [1] "two-sample-dependent" # n-sample dependent (blocked): treatment, not group r4 <- resolveFormula(y ~ trt | blk, data = df, allowed = "n-sample-dependent") names(r4) ## [1] "type" "mf" "rows" "response" "treatment" "block" "dataName" # numeric-numeric: predictor, not group df3 <- data.frame(y = rnorm(20), x = rnorm(20)) r5 <- resolveFormula(y ~ x, data = df3, allowed = "numeric-numeric") is.numeric(r5$predictor) ## [1] TRUE # regression: build the design matrix from 'terms', not from the formula r6 <- resolveFormula(y ~ log(abs(x)) + I(x^2), data = df3, allowed = "regression") colnames(model.matrix(r6$terms, r6$mf)) # subset, as in base R resolveFormula(y ~ g3, data = df, subset = g3 != "C", allowed = "two-sample-independent")$type ## [1] "two-sample-independent"
Brings grouped data into one canonical shape, no matter which of the two usual interfaces the caller was given: a response vector together with a grouping variable, or a list holding one vector per group. The function validates the input, drops missing values, builds the grouping factor and returns the commonly needed group information, providing a shared entry point for hypothesis tests, summaries, effect-size calculations and plotting functions.
resolveGroups(x, groups)resolveGroups(x, groups)
x |
a numeric vector of observations, or a list of numeric vectors, one per group. A data frame is a list and is accepted as one, every column being taken as a group. |
groups |
a grouping variable, a vector of the same length as |
The two input forms are treated as equivalent. For a list, every element is
taken as one group and groups is ignored with a warning. For a vector,
groups is coerced to a factor after the incomplete observations have been
removed, so that empty levels are dropped. The levels of an input that
already is a factor keep their order, everything else is ordered as
factor() produces it.
The names of a list become the group labels and their order becomes the
order of the levels. As these labels end up in printed results, they must be
complete and unique; a partially or ambiguously named list is an error
rather than being silently renamed. A list without any names is labelled
"1", "2", and so on.
A data frame is a list of columns and is resolved as one, which covers the
common case of one group per column. Its column names are complete and
unique by construction and are used as the group labels. Note that the
groups of a data frame all have the same length before the missing values
are removed, so a ragged design has to be padded with NA or passed as a
plain list.
Missing values are removed in both cases, but along different rules. From a
list every NA and NaN in a group is dropped, from a vector those
observations are dropped where either the response or the grouping variable
is missing. What remains must leave at least two groups, each of them
non-empty.
The returned dataName is built from the unevaluated arguments and is meant
to be passed on to the data.name element of an htest object. It reads as
"x and g" for a vector with a grouping variable and as the deparsed
expression itself for a list.
a list containing:
numeric vector of the observations, missing values removed. For a list input the groups follow each other in the order of the list.
factor of the same length as x holding the group
membership.
integer, the total number of observations.
integer, the number of groups.
named integer vector of the group sample sizes, in the order of the levels.
character vector of the group labels, the levels of
groups.
character description of the input, for use as the
data.name of an htest object.
Other data.resolve:
resolveContingency(),
resolveFormula()
# vector + grouping variable set.seed(1) x <- rnorm(30) g <- rep(c("a", "b", "c"), each = 10) str(resolveGroups(x, g)) # list of group-specific vectors, the names become the labels resolveGroups(list(a = rnorm(10), b = rnorm(12), c = rnorm(8)))[c("k", "groupSizes")] # both interfaces lead to the same result identical(resolveGroups(x, g)$groupSizes, resolveGroups(split(x, g))$groupSizes) # a data frame is resolved column by column resolveGroups(data.frame(ctrl = c(1, 2, 3), treat = c(4, 5, NA)))$groupSizes# vector + grouping variable set.seed(1) x <- rnorm(30) g <- rep(c("a", "b", "c"), each = 10) str(resolveGroups(x, g)) # list of group-specific vectors, the names become the labels resolveGroups(list(a = rnorm(10), b = rnorm(12), c = rnorm(8)))[c("k", "groupSizes")] # both interfaces lead to the same result identical(resolveGroups(x, g)$groupSizes, resolveGroups(split(x, g))$groupSizes) # a data frame is resolved column by column resolveGroups(data.frame(ctrl = c(1, 2, 3), treat = c(4, 5, NA)))$groupSizes
Reverses the coding of a vector. Supports numeric, logical, and factor inputs:
Numeric: Transforms values using min + max - x
Logical: Flips TRUE/FALSE
Factor: Reverses the order of levels
revCode(x, min = NULL, max = NULL, na.rm = FALSE)revCode(x, min = NULL, max = NULL, na.rm = FALSE)
x |
a vector (numeric, logical, or factor). |
min |
optional numeric minimum. Must be provided together with |
max |
optional numeric maximum. Must be provided together with |
na.rm |
logical; whether to ignore |
a vector of the same type and length as x, with reversed coding.
Throws an error if all values are NA, if only one of min/max
is provided, if min > max, or if x is not numeric, logical, or factor.
A warning is issued if values of x lie outside an explicitly
provided [min, max] range.
Other data.recode:
asBinary(),
combLevels(),
dummy(),
mReplace(),
nf(),
recodeX(),
stringsAsFactors()
# Numeric revCode(c(1, 2, 3, 4, 5)) # Numeric with explicit range (e.g., Likert scale) revCode(c(1, 2, 3, 4, 5), min = 1, max = 5) # Numeric with NAs revCode(c(1, 2, NA, 4, 5), na.rm = TRUE) # Logical revCode(c(TRUE, FALSE, TRUE)) # Factor x <- factor(c("low", "medium", "high"), ordered = TRUE) revCode(x)# Numeric revCode(c(1, 2, 3, 4, 5)) # Numeric with explicit range (e.g., Likert scale) revCode(c(1, 2, 3, 4, 5), min = 1, max = 5) # Numeric with NAs revCode(c(1, 2, NA, 4, 5), na.rm = TRUE) # Logical revCode(c(TRUE, FALSE, TRUE)) # Factor x <- factor(c("low", "medium", "high"), ordered = TRUE) revCode(x)
Returns a reversed version of its argument. Where rev() treats every
object as one long vector, revX()
reverses the order along the dimensions of a multidimensional object,
so that a matrix, table, array or data frame comes
back with its rows, its columns, or both, in the opposite order and its
dimnames moved along with the data. Which dimensions are turned around is
chosen with margin.
revX(x, ...) ## Default S3 method: revX(x, margin = 1L, ...) ## S3 method for class 'array' revX(x, margin = seq_along(dim(x)), ...) ## S3 method for class 'matrix' revX(x, margin = seq_along(dim(x)), ...) ## S3 method for class 'table' revX(x, margin = seq_along(dim(x)), ...) ## S3 method for class 'data.frame' revX(x, margin = 1:2, ...)revX(x, ...) ## Default S3 method: revX(x, margin = 1L, ...) ## S3 method for class 'array' revX(x, margin = seq_along(dim(x)), ...) ## S3 method for class 'matrix' revX(x, margin = seq_along(dim(x)), ...) ## S3 method for class 'table' revX(x, margin = seq_along(dim(x)), ...) ## S3 method for class 'data.frame' revX(x, margin = 1:2, ...)
x |
a vector, matrix, table, array or data frame to be reversed. |
... |
further arguments, passed on to the method dispatched on. This
is how |
margin |
the dimensions to reverse, |
A vector has one dimension and is simply reversed, as by rev(), with
margin = 1 accepted so that calling code need not know whether its
argument has dimensions. For everything else, margin names the dimensions to be reversed, 1 for the
rows, 2 for the columns, and so on for the higher dimensions of an array;
the default reverses all of them. The values in the object are not
rearranged relative to their labels: reversing an object twice along the
same margin returns the original.
margin names each dimension at most once; repeating one says nothing and
is refused, as is any value outside the dimensions of x.
The additional arguments of the generic are the way margin reaches the
methods. Anything else is ignored with a warning, rather than being dropped
silently although it was meant to change the result.
an object of the same class and dimensions as x, with the order of
the elements along margin reversed.
Other data.order:
binaryTree(),
sortX()
tab <- matrix(c(1, 11, 111, 2, 22, 222, 3, 33, 333), byrow=TRUE, nrow=3, dimnames=list(mar1=1:3, mar2=c("a","b","c"))) revX(tab, margin=1) revX(tab, margin=2) # reverse both dimensions revX(tab, margin=c(1, 2)) # the dimnames travel with the data, so this is not a transposition revX(tab, margin=c(1, 2))["3", "a"] == tab["3", "a"] ## [1] TRUE # reverse a 3-dimensional array aa <- array(c(tab, 2 * tab), dim = c(3, 3, 2), dimnames = c(dimnames(tab), list(mar3 = c("A", "Z")))) # reverse rows revX(aa, 1) # reverse columns revX(aa, 2) # reverse the third dimension revX(aa, 3) # reverse all dimensions revX(aa) # same as revX(aa, margin = 1:3) # data frames are reversed by rows, by columns or both d <- data.frame(a = 1:3, b = 4:6) revX(d, 1) revX(d, 2)tab <- matrix(c(1, 11, 111, 2, 22, 222, 3, 33, 333), byrow=TRUE, nrow=3, dimnames=list(mar1=1:3, mar2=c("a","b","c"))) revX(tab, margin=1) revX(tab, margin=2) # reverse both dimensions revX(tab, margin=c(1, 2)) # the dimnames travel with the data, so this is not a transposition revX(tab, margin=c(1, 2))["3", "a"] == tab["3", "a"] ## [1] TRUE # reverse a 3-dimensional array aa <- array(c(tab, 2 * tab), dim = c(3, 3, 2), dimnames = c(dimnames(tab), list(mar3 = c("A", "Z")))) # reverse rows revX(aa, 1) # reverse columns revX(aa, 2) # reverse the third dimension revX(aa, 3) # reverse all dimensions revX(aa) # same as revX(aa, margin = 1:3) # data frames are reversed by rows, by columns or both d <- data.frame(a = 1:3, b = 4:6) revX(d, 1) revX(d, 2)
The numbers on a single-zero (European) Roulette wheel and their associated properties: colour, betting categories and the traditional sectors of the wheel. Each row represents one of the 37 numbers (0–36).
RouletteRoulette
A data frame with 37 rows and 7 variables:
integer, the number in the pocket (0–36).
factor, colour of the pocket: red, black or green.
factor, even or odd.
factor, low (1–18) or high (19–36).
factor, dozen on the table: 1 (1–12), 2 (13–24),
3 (25–36).
factor, column on the table: 1, 2 or 3, counted
from the one containing 1.
factor, sector of the wheel: jeu zero,
voisins du zero, tiers du cylindre or orphelins.
The dataset can be used for teaching probability and categorical data analysis, as well as for simulating Roulette betting strategies.
The rows are ordered as the pockets follow each other on the wheel,
starting at zero, and not by num. The sectors in pocketrange are
therefore contiguous blocks of rows.
Zero takes part in none of the even/odd, high/low, dozen and column
bets, so these variables are NA for zero. Note that this follows the
rules of the game and not arithmetic, where zero would count as even.
The seven numbers of the jeu zero are part of the voisins du zero
in the usual reading of the terms. As every number appears exactly once
here, they are reported as a separate level and voisins du zero
covers the remaining ten numbers of that sector.
Accents are dropped in the factor levels (voisins du zero for
voisins du zéro).
The standard layout of a single-zero Roulette wheel.
Other datasets:
Cards,
Pizza,
Tarot,
readCourseData()
head(Roulette) table(Roulette$col) table(Roulette$parity, Roulette$highlow, useNA = "ifany") # the sectors of the wheel are blocks of neighbouring pockets table(Roulette$pocketrange)head(Roulette) table(Roulette$col) table(Roulette$parity, Roulette$highlow, useNA = "ifany") # the sectors of the wheel are blocks of neighbouring pockets table(Roulette$pocketrange)
Rounds the values of a numeric vector to the nearest multiple of a given
step width. Where round() is tied to multiples of a power of ten,
roundTo() accepts an arbitrary step, so that prices can be rounded to the
nearest 5 cents, durations to the nearest quarter of an hour or axis limits
to the nearest 250. The direction of the rounding is controlled by FUN,
which allows rounding to the nearest, upwards, downwards or towards zero
with the same interface.
roundTo(x, multiple = 1, FUN = round)roundTo(x, multiple = 1, FUN = round)
x |
numeric. The values to be rounded. |
multiple |
numeric. The step width to whose multiples the values are to
be rounded, defaults to |
FUN |
the rounding function applied to |
There are several functions in base R to convert to integers. round()
rounds to the nearest integer or to any number of digits. Using a negative
number of digits rounds to a power of ten, so that round(x, -3) rounds to
thousands. Each of trunc(), floor() and ceiling() rounds in a fixed
direction, towards zero, down and up respectively. round() is documented
to round half to even, so round(2.5) is 2.
roundTo() evaluates FUN(x / multiple) * multiple. With the default
FUN = round a value lying exactly halfway between two multiples is
therefore rounded to the one with the even quotient: roundTo(1, 2) is 0
and roundTo(3, 2) is 4. Setting FUN = ceiling always rounds up,
FUN = floor always rounds down and FUN = trunc always towards zero (see
the examples for a comparison).
Ties are rare in practice, as most decimal fractions have no exact binary
representation. 1.3 / 0.2 is marginally smaller than 6.5 in double
precision, so roundTo(1.3, 0.2) returns 1.2 and not the 1.4 that the
rule for ties would suggest. Results for a fractional multiple are
likewise only accurate to within representation error, which is why
roundTo(x, 0.05) may still print more than two decimal places.
A single multiple is used for all the values in x. A vector of step
widths is applied elementwise and must then be exactly as long as x, so
that a length mismatch is reported as an error instead of being recycled
silently.
a numeric vector of the rounded values, as long as x. NAs in x
are returned as NA.
round(), trunc(), ceiling(), floor()
Other math.basic:
closest(),
crossProd(),
crossProdN(),
dotProd(),
unirootAll()
roundTo(10, 3) # rounds 10 to the nearest multiple of 3 (9) roundTo(-10, 3) # rounds -10 to the nearest multiple of 3 (-9) roundTo(1.3, 0.2) # rounds 1.3 to the nearest multiple of 0.2 (1.2) roundTo(-1.3, 0.2) # rounds -1.3 to the nearest multiple of 0.2 (-1.2) # prices to the nearest 5 cents roundTo(c(1.02, 1.03, 12.375), 0.05) # a step width for every value roundTo(c(1.23, 123, 1234), c(0.05, 10, 100)) # any other length is an error, the values are not recycled try(roundTo(1:6, c(2, 3))) # round down roundTo(c(1, -1) * 1.2335, 0.05, floor) roundTo(c(1, -1) * 1233.5, 100, floor) # round up roundTo(c(1, -1) * 1.2335, 0.05, ceiling) roundTo(c(1, -1) * 1233.5, 100, ceiling) # round towards zero roundTo(c(1, -1) * 1.2335, 0.05, trunc) roundTo(c(1, -1) * 1233.5, 100, trunc) # the four directions side by side x <- c(-1.5, -1.3, 1.3, 1.5) cbind(x = x, round = roundTo(x, 0.2, FUN = round), trunc = roundTo(x, 0.2, FUN = trunc), ceiling = roundTo(x, 0.2, FUN = ceiling), floor = roundTo(x, 0.2, FUN = floor) ) # note how the ties in the first column are resolved to even multiples x <- -5:5 cbind(x = x, round = roundTo(x, 2, FUN = round), trunc = roundTo(x, 2, FUN = trunc), ceiling = roundTo(x, 2, FUN = ceiling), floor = roundTo(x, 2, FUN = floor) )roundTo(10, 3) # rounds 10 to the nearest multiple of 3 (9) roundTo(-10, 3) # rounds -10 to the nearest multiple of 3 (-9) roundTo(1.3, 0.2) # rounds 1.3 to the nearest multiple of 0.2 (1.2) roundTo(-1.3, 0.2) # rounds -1.3 to the nearest multiple of 0.2 (-1.2) # prices to the nearest 5 cents roundTo(c(1.02, 1.03, 12.375), 0.05) # a step width for every value roundTo(c(1.23, 123, 1234), c(0.05, 10, 100)) # any other length is an error, the values are not recycled try(roundTo(1:6, c(2, 3))) # round down roundTo(c(1, -1) * 1.2335, 0.05, floor) roundTo(c(1, -1) * 1233.5, 100, floor) # round up roundTo(c(1, -1) * 1.2335, 0.05, ceiling) roundTo(c(1, -1) * 1233.5, 100, ceiling) # round towards zero roundTo(c(1, -1) * 1.2335, 0.05, trunc) roundTo(c(1, -1) * 1233.5, 100, trunc) # the four directions side by side x <- c(-1.5, -1.3, 1.3, 1.5) cbind(x = x, round = roundTo(x, 0.2, FUN = round), trunc = roundTo(x, 0.2, FUN = trunc), ceiling = roundTo(x, 0.2, FUN = ceiling), floor = roundTo(x, 0.2, FUN = floor) ) # note how the ties in the first column are resolved to even multiples x <- -5:5 cbind(x = x, round = roundTo(x, 2, FUN = round), trunc = roundTo(x, 2, FUN = trunc), ceiling = roundTo(x, 2, FUN = ceiling), floor = roundTo(x, 2, FUN = floor) )
Generates a vector of random proportions that sum exactly to 1.
rSum21(size, digits = NULL)rSum21(size, digits = NULL)
size |
integer. The number of values to generate. |
digits |
integer. If not |
The values are drawn from a uniform distribution and normalized by their
sum. If digits is given, the values are rounded and the rounding
error is assigned to the largest element, which is then rounded again to
the requested precision. Note that for very coarse rounding the exact-sum
guarantee may not be attainable at the given precision.
a numeric vector of length size summing to 1.
Other random.numbers:
rBetaShape()
x <- rSum21(5) sum(x) x <- rSum21(5, digits = 2) sum(x)x <- rSum21(5) sum(x) x <- rSum21(5, digits = 2) sum(x)
sampleX takes a sample of the specified size from the elements
of x, with or without replacement. It does the same as
sample() and additionally offers an interface for data
frames, where rows are sampled.
sampleX(x, size, replace = FALSE, prob = NULL) ## S3 method for class 'data.frame' sampleX(x, size = nrow(x), replace = FALSE, prob = NULL) ## Default S3 method: sampleX(x, size, replace = FALSE, prob = NULL)sampleX(x, size, replace = FALSE, prob = NULL) ## S3 method for class 'data.frame' sampleX(x, size = nrow(x), replace = FALSE, prob = NULL) ## Default S3 method: sampleX(x, size, replace = FALSE, prob = NULL)
x |
either a vector of one or more elements from which to choose, or a positive integer, or a data frame whose rows are to be sampled. |
size |
a non-negative integer giving the number of items (or rows)
to choose. If missing, it defaults to the number of elements of |
replace |
logical; whether sampling is performed with replacement. |
prob |
a vector of probability weights for obtaining the elements (or rows) being sampled. |
sampled elements in the same structure as x; for data
frames, a data frame containing the sampled rows.
Other combinatorics:
combN(),
combPairs(),
combSet(),
pairApply(),
permn(),
randGroupSplit()
sampleX(1:10, size = 5) # random permutation, like sample(x) sampleX(1:10) # sample rows of a data frame sampleX(mtcars, size = 5)sampleX(1:10, size = 5) # random permutation, like sample(x) sampleX(1:10) # sample rows of a data frame sampleX(mtcars, size = 5)
Convenience helpers to add, remove, or selectively retain attributes of an object.
setAttr(x, attrNames, attrValues) removeAttr(x, attrNames = NULL) keepAttr(x, attrNames)setAttr(x, attrNames, attrValues) removeAttr(x, attrNames = NULL) keepAttr(x, attrNames)
x |
object to modify. |
attrNames |
character vector of attribute names. |
attrValues |
values for the attributes (only for setting). For a
single attribute name, |
modified object.
Other label.attrs:
label(),
renameX(),
setNamesX()
x <- runif(10) x <- setAttr( x, attrNames = c("some_attr", "other_attr"), attrValues = c("First attribute", "Second attribute") ) # a single attribute can take a vector value setAttr(1:10, "dim", c(2, 5)) # several non-scalar values via list setAttr(1:10, c("dim", "myattr"), list(c(2, 5), "abc")) # remove single attribute removeAttr(x, "other_attr") # remove all attributes removeAttr(x) # keep only selected attributes, remove all others r.lm <- lm(Fertility ~ ., swiss) keepAttr(r.lm$terms, "class")x <- runif(10) x <- setAttr( x, attrNames = c("some_attr", "other_attr"), attrValues = c("First attribute", "Second attribute") ) # a single attribute can take a vector value setAttr(1:10, "dim", c(2, 5)) # several non-scalar values via list setAttr(1:10, c("dim", "myattr"), list(c(2, 5), "abc")) # remove single attribute removeAttr(x, "other_attr") # remove all attributes removeAttr(x) # keep only selected attributes, remove all others r.lm <- lm(Fertility ~ ., swiss) keepAttr(r.lm$terms, "class")
Extends x to length n by appending fill, or
truncates it to length n if it is already longer – like
length(x) <- n, but with a configurable fill value instead
of NA.
setLength(x, n, fill = NA)setLength(x, n, fill = NA)
x |
a vector. |
n |
target length, a single non-negative whole number. |
fill |
value used for newly added elements when |
x, of length n.
Other vector.reshape:
trim(),
vRot(),
vShift()
setLength(LETTERS[1:3], 5) setLength(LETTERS[1:3], 2) setLength(1:4, 6, fill = 0)setLength(LETTERS[1:3], 5) setLength(LETTERS[1:3], 2) setLength(1:4, 6, fill = 0)
This is a convenience function that sets the names of an object and returns
it including the new names. It is most useful at the end of a function
definition where one is creating the object to be returned and would prefer
not to store it under a name just that the names can be assigned. In
addition to the function setNames() in base R the user can
decide, whether rownames, colnames or simply the names are to be set.
setNamesX(x, ...)setNamesX(x, ...)
x |
an object for which a names attribute will be meaningful. |
... |
the names to be assigned to the object. This should be a
character vector of names named |
A name of length one is recycled to the required extent, which is handy for
blanking out names with "". Names of any other length must match the
extent of the object exactly; a deviating length is reported as an error
rather than being recycled silently, as an unexpected length is almost
always a miscalculation upstream and duplicated names are hard to debug
later on.
an object of the same sort as object with the new names assigned.
Other label.attrs:
label(),
renameX(),
setAttr-removeAttr-keepAttr
setNamesX(1:5, names=letters[1:5]) # the default, if no argument names are provided, is "names" setNamesX(1:5, letters[1:5]) # rownames and columnnames can be set at the same time setNamesX(matrix(c(1:12), nrow=4), rownames=LETTERS[11:14], colnames=c("perc", "lci", "uci")) # a single name is recycled, so this sets all the names to an empty string setNamesX(diag(6), rownames="", colnames="") # any other length must fit, a mismatch is an error try(setNamesX(matrix(c(1:12), nrow=4), colnames=c("perc", "lci"))) # setting dimnames works as well tab <- setNamesX( as.table(rbind(c(84,43), c(10,92))), dimnames= list( dipstick=c("positive","negative"), culture=c("positive","negative")))setNamesX(1:5, names=letters[1:5]) # the default, if no argument names are provided, is "names" setNamesX(1:5, letters[1:5]) # rownames and columnnames can be set at the same time setNamesX(matrix(c(1:12), nrow=4), rownames=LETTERS[11:14], colnames=c("perc", "lci", "uci")) # a single name is recycled, so this sets all the names to an empty string setNamesX(diag(6), rownames="", colnames="") # any other length must fit, a mismatch is an error try(setNamesX(matrix(c(1:12), nrow=4), colnames=c("perc", "lci"))) # setting dimnames works as well tab <- setNamesX( as.table(rbind(c(84,43), c(10,92))), dimnames= list( dipstick=c("positive","negative"), culture=c("positive","negative")))
sortX extends the base sort() function by providing
a consistent interface for sorting not only vectors, but also matrices,
tables, and data frames. For 2-dimensional objects, rows are sorted based
on one or more columns.
sortX(x, ...) ## Default S3 method: sortX( x, decreasing = FALSE, na.last = NA, method = c("default", "mixed"), factorsAsCharacter = TRUE, ... ) ## S3 method for class 'table' sortX( x, by = NULL, decreasing = FALSE, na.last = TRUE, method = c("default", "mixed"), factorsAsCharacter = TRUE, ... ) ## S3 method for class 'matrix' sortX( x, by = NULL, decreasing = FALSE, na.last = TRUE, method = c("default", "mixed"), factorsAsCharacter = TRUE, ... ) ## S3 method for class 'data.frame' sortX( x, by = NULL, decreasing = FALSE, na.last = TRUE, method = c("default", "mixed"), factorsAsCharacter = TRUE, ... )sortX(x, ...) ## Default S3 method: sortX( x, decreasing = FALSE, na.last = NA, method = c("default", "mixed"), factorsAsCharacter = TRUE, ... ) ## S3 method for class 'table' sortX( x, by = NULL, decreasing = FALSE, na.last = TRUE, method = c("default", "mixed"), factorsAsCharacter = TRUE, ... ) ## S3 method for class 'matrix' sortX( x, by = NULL, decreasing = FALSE, na.last = TRUE, method = c("default", "mixed"), factorsAsCharacter = TRUE, ... ) ## S3 method for class 'data.frame' sortX( x, by = NULL, decreasing = FALSE, na.last = TRUE, method = c("default", "mixed"), factorsAsCharacter = TRUE, ... )
x |
a numeric, complex, character or logical vector, factor, matrix, table, or data frame to be sorted. |
... |
further arguments passed to |
decreasing |
logical scalar or vector. Should the sort be in
decreasing order? For 2-dimensional objects a vector of the same length
as |
na.last |
logical or |
method |
sorting method. Either |
factorsAsCharacter |
logical. If |
by |
integer or character vector specifying the columns to sort by,
and their priority (first element = primary key). Column names and
positive integer indices ( |
By default, sorting follows the behavior of base R. In addition,
method = "mixed" enables natural ("human-friendly") sorting of
character data, e.g. "A2" < "A10".
For method = "mixed", sorting is applied column-wise using
.orderMixed(). Each column's tokens are ordered independently
(numeric runs numerically, text runs lexicographically) before the
results are combined via stable right-to-left ordering.
The sort order for factors depends on factorsAsCharacter:
if TRUE (default), factors are sorted by their labels
(alphabetically or by natural order when method = "mixed");
if FALSE, they are sorted by their level order, which is
appropriate for ordered factors but may be unintuitive for unordered ones.
the sorted object, of the same class as x.
Other data.order:
binaryTree(),
revX()
set.seed(3) d.frm <- iris[sample(nrow(iris), 10), c("Species", "Sepal.Length", "Sepal.Width")] # Vector sorting sortX(d.frm[, 1]) # Data frame: sort by column name sortX(d.frm, by = "Species") sortX(d.frm, by = c("Species", "Sepal.Length")) # Data frame: sort by column index sortX(d.frm, by = c(1L, 2L)) # Decreasing order (per-column control) sortX(d.frm, by = c("Species", "Sepal.Length"), decreasing = c(FALSE, TRUE)) # Natural sorting of character vectors x <- c("A1", "A10", "A2") sortX(x, method = "mixed") # Factor: sort by label (default) vs. level order sortX(d.frm, by = "Species") # by label sortX(d.frm, by = "Species", factorsAsCharacter = FALSE) # by level # Tables: sort by column 2 descending tab <- HairEyeColor[, , 1] sortX(tab, by = 2L, decreasing = TRUE) # Tables: sort by marginal row sums sortX(tab, by = ncol(tab) + 1L, decreasing = TRUE) # Sort by row names (always pass 0 as integer) sortX(tab, by = 0L)set.seed(3) d.frm <- iris[sample(nrow(iris), 10), c("Species", "Sepal.Length", "Sepal.Width")] # Vector sorting sortX(d.frm[, 1]) # Data frame: sort by column name sortX(d.frm, by = "Species") sortX(d.frm, by = c("Species", "Sepal.Length")) # Data frame: sort by column index sortX(d.frm, by = c(1L, 2L)) # Decreasing order (per-column control) sortX(d.frm, by = c("Species", "Sepal.Length"), decreasing = c(FALSE, TRUE)) # Natural sorting of character vectors x <- c("A1", "A10", "A2") sortX(x, method = "mixed") # Factor: sort by label (default) vs. level order sortX(d.frm, by = "Species") # by label sortX(d.frm, by = "Species", factorsAsCharacter = FALSE) # by level # Tables: sort by column 2 descending tab <- HairEyeColor[, , 1] sortX(tab, by = 2L, decreasing = TRUE) # Tables: sort by marginal row sums sortX(tab, by = ncol(tab) + 1L, decreasing = TRUE) # Sort by row names (always pass 0 as integer) sortX(tab, by = 0L)
Splits a vector into consecutive segments at specified positions.
splitAt(x, pos)splitAt(x, pos)
x |
a vector to be split. |
pos |
an integer vector of positions at which to split |
The function splits x into consecutive chunks defined by pos.
Internally, positions are sorted, duplicates are removed, and values that
would not produce a non-empty segment (pos < 2 or
pos > length(x)) are ignored. Empty segments are never returned.
Each element of the returned list corresponds to a contiguous subset of
x. The first segment always starts at position 1.
a list of vectors, each representing a segment of x.
Other data.reshape:
collapseTable(),
long-wide-reshape,
splitX(),
untable()
x <- 1:10 # split at positions 4 and 7 splitAt(x, c(4, 7)) # unsorted and duplicate positions are handled splitAt(x, c(7, 4, 4, 20))x <- 1:10 # split at positions 4 and 7 splitAt(x, c(4, 7)) # unsorted and duplicate positions are handled splitAt(x, c(7, 4, 4, 20))
Splits a file path into its components such as directory, file name, and extension. The function is OS-aware and works on both Windows and Unix-like systems.
splitPath(path, lastIsFile = NULL)splitPath(path, lastIsFile = NULL)
path |
a character vector of file paths. |
lastIsFile |
logical; if |
The function uses basename() and dirname() for
platform-independent path handling. File name and extension are extracted
using tools::file_path_sans_ext() and tools::file_ext().
If lastIsFile = FALSE, the path is treated as a directory and
file-related components (fullfilename, filename,
extension) are returned as NA.
a list with the following components (each a vector of the same
length as path):
normalized path as returned by normalizePath().
drive letter on Windows systems (e.g., "C:"),
otherwise NA.
directory path without drive letter, including trailing separator.
full file name including extension (if applicable).
full directory path including drive letter and trailing separator.
file name without extension.
file extension without leading dot.
basename(), dirname(),
tools::file_ext(), tools::file_path_sans_ext()
Other file.path:
buildPath(),
findDownload(),
isFilePath(),
isUrl(),
urlExists()
splitPath("C:/temp/file.txt") splitPath("/home/user/data.csv") # treat as directory splitPath("/home/user/folder/", lastIsFile = FALSE)splitPath("C:/temp/file.txt") splitPath("/home/user/data.csv") # treat as directory splitPath("/home/user/folder/", lastIsFile = FALSE)
Splits a vector or object into groups defined by a factor or grouping variables.
This is a wrapper around split() with an additional
formula interface.
splitX(x, ...) ## Default S3 method: splitX(x, f, drop = FALSE, ...) ## S3 method for class 'formula' splitX(formula, data, subset, na.action, drop = FALSE, ...)splitX(x, ...) ## Default S3 method: splitX(x, f, drop = FALSE, ...) ## S3 method for class 'formula' splitX(formula, data, subset, na.action, drop = FALSE, ...)
x |
object to be split (typically a vector). |
... |
further arguments passed to |
f |
a factor or list of factors defining the groups (default method). |
drop |
logical; if |
formula |
a formula of the form |
data |
a data frame containing the variables in the formula. |
subset |
optional logical expression indicating rows to include. |
na.action |
a function specifying how missing values are handled,
passed to |
splitX extends split() by providing:
an S3 interface
a formula method for convenient specification of variables
support for multiple grouping variables via formula
The formula interface evaluates a model.frame() and splits
the response variable by one or more grouping variables.
If multiple grouping variables are provided, the data are split by their
interaction (similar to split(..., interaction(...))).
a list of subsets of x, grouped according to f or the
grouping variables in the formula.
Other data.reshape:
collapseTable(),
long-wide-reshape,
splitAt(),
untable()
# Default usage x <- 1:10 g <- rep(letters[1:2], each = 5) splitX(x, g) # Formula interface df <- data.frame( y = rnorm(10), g1 = rep(letters[1:2], each = 5), g2 = rep(1:2, times = 5) ) splitX(y ~ g1, data = df) splitX(y ~ g1 + g2, data = df)# Default usage x <- 1:10 g <- rep(letters[1:2], each = 5) splitX(x, g) # Formula interface df <- data.frame( y = rnorm(10), g1 = rep(letters[1:2], each = 5), g2 = rep(1:2, times = 5) ) splitX(y ~ g1, data = df) splitX(y ~ g1 + g2, data = df)
Strings as factors have recently been downgraded in base R's
data.frame() function. However,
it is still usually a good idea to encode string variables
as factors. This function helps to convert some or
all columns of a data.frame to factors.
stringsAsFactors(x, columns = NULL)stringsAsFactors(x, columns = NULL)
x |
the data.frame. |
columns |
names or indexes of the columns to be converted; negative values can be used to omit columns. |
the given data.frame including the converted factors.
Other data.recode:
asBinary(),
combLevels(),
dummy(),
mReplace(),
nf(),
recodeX(),
revCode()
d.dat <- data.frame(char_x = LETTERS[1:5], char_y = LETTERS[6:10], n = 1:5) # all character columns str(stringsAsFactors(d.dat)) # only char_y str(stringsAsFactors(d.dat, columns = "char_y")) # only char_x str(stringsAsFactors(d.dat, columns = "char_x")) # all character columns except the second one ("char_y") str(stringsAsFactors(d.dat, columns = -2))d.dat <- data.frame(char_x = LETTERS[1:5], char_y = LETTERS[6:10], n = 1:5) # all character columns str(stringsAsFactors(d.dat)) # only char_y str(stringsAsFactors(d.dat, columns = "char_y")) # only char_x str(stringsAsFactors(d.dat, columns = "char_x")) # all character columns except the second one ("char_y") str(stringsAsFactors(d.dat, columns = -2))
Splits character vectors into multiple columns based on a delimiter.
Each element of x is split using strsplit(),
and the resulting parts are expanded into separate columns.
strSplitToCol(x, split = " ", fixed = TRUE, naForm = "", colNames = NULL)strSplitToCol(x, split = " ", fixed = TRUE, naForm = "", colNames = NULL)
x |
a character vector or a data frame of character columns to be split. Each element (or column) is processed separately. |
split |
character string specifying the delimiter for splitting.
Passed to |
fixed |
logical; if |
naForm |
character value used to replace missing elements created by unequal split lengths. |
colNames |
optional character vector specifying column names for the resulting data frame. Recycled if necessary. |
All rows are padded to the same number of columns per input element.
Missing values are filled with naForm.
For each element (or column) in x, the function:
Splits each entry using strsplit()
Determines the maximum number of split parts
Pads shorter splits with naForm
Combines results into a matrix via rbind()
The final result is a data frame where each original element or column contributes one or more columns depending on the number of splits.
An attribute "cols" is attached, indicating the number of columns
generated for each element of x.
a data frame containing the split components of x.
Additional attribute:
cols: integer vector with number of columns per input element.
Other string.transform:
char-ascii-conversion,
mGsub(),
strSplitToDummy()
x <- c("A B C", "D E", "F") strSplitToCol(x) # Custom delimiter x <- c("A|B|C", "D|E", "F") strSplitToCol(x, split = "|") # Multiple columns df <- data.frame( a = c("x y", "z"), b = c("1 2 3", "4 5"), stringsAsFactors = FALSE ) strSplitToCol(df)x <- c("A B C", "D E", "F") strSplitToCol(x) # Custom delimiter x <- c("A|B|C", "D|E", "F") strSplitToCol(x, split = "|") # Multiple columns df <- data.frame( a = c("x y", "z"), b = c("1 2 3", "4 5"), stringsAsFactors = FALSE ) strSplitToCol(df)
Splits a character vector of delimited tokens into a binary dummy data.frame where each unique token becomes a column.
strSplitToDummy(x, split = ",", trim = TRUE, na.action = na.pass, ...)strSplitToDummy(x, split = ",", trim = TRUE, na.action = na.pass, ...)
x |
a character vector with delimited tokens. |
split |
a character string to use as delimiter. Default is |
trim |
logical. If |
na.action |
a function to handle
|
... |
additional arguments passed to |
a data.frame with one row per element of x and one
column per unique token. Values are 0L or 1L. Column names
are the token values as-is and may not be syntactically valid R
identifiers. The attribute "tokens" contains the sorted vector of
unique tokens.
Other string.transform:
char-ascii-conversion,
mGsub(),
strSplitToCol()
dat <- data.frame(id = 1:5, txt = c("A,C,D", "A", "B,C", "D", "D,E")) # default: NA passed through as zero row strSplitToDummy(dat$txt) # with an NA in the input x_na <- c("A,B", "B,C", NA, "A") # na.pass: NA becomes an all-zero row (default) strSplitToDummy(x_na, na.action = na.pass) # na.omit: NA rows are silently dropped strSplitToDummy(x_na, na.action = na.omit) # na.exclude: like na.omit but NA indices stored in attribute res <- strSplitToDummy(x_na, na.action = na.exclude) attr(res, "na.action") # na.fail: error if any NA present tryCatch( strSplitToDummy(x_na, na.action = na.fail), error = function(e) conditionMessage(e) )dat <- data.frame(id = 1:5, txt = c("A,C,D", "A", "B,C", "D", "D,E")) # default: NA passed through as zero row strSplitToDummy(dat$txt) # with an NA in the input x_na <- c("A,B", "B,C", NA, "A") # na.pass: NA becomes an all-zero row (default) strSplitToDummy(x_na, na.action = na.pass) # na.omit: NA rows are silently dropped strSplitToDummy(x_na, na.action = na.omit) # na.exclude: like na.omit but NA indices stored in attribute res <- strSplitToDummy(x_na, na.action = na.exclude) attr(res, "na.action") # na.fail: error if any NA present tryCatch( strSplitToDummy(x_na, na.action = na.fail), error = function(e) conditionMessage(e) )
Wrapper around str() that optionally numbers variables in
lists and data frames. Useful for large objects where variables should
be referenced by position.
strX(object, ..., enumerate = TRUE, recursive = FALSE, strict.width = "cut")strX(object, ..., enumerate = TRUE, recursive = FALSE, strict.width = "cut")
object |
any R object. |
... |
additional arguments passed to |
enumerate |
logical; whether variables or elements are numbered.
Default is |
recursive |
logical; whether nested list elements are also numbered.
Default is |
strict.width |
character string passed to |
By default, only top-level elements are numbered. Recursive numbering
of nested list elements can be enabled with recursive = TRUE; nested
elements then get hierarchical labels such as 2.1, which give their
position (x[[2]][[1]]), and the top-level numbers stay the same in both
views.
invisibly returns the character vector produced by str().
# Data frame strX(mtcars) # Nested list x <- list( a = 1, b = list( c = 2, d = 3 ) ) strX(x) # Recursive numbering strX(x, recursive = TRUE)# Data frame strX(mtcars) # Nested list x <- list( a = 1, b = list( c = 2, d = 3 ) ) strX(x) # Recursive numbering strX(x, recursive = TRUE)
A dataset representing a standard Tarot deck, including both Major and Minor Arcana Cards. Each row corresponds to a single card with attributes describing its type, suit and rank.
TarotTarot
A data frame with 78 observations and 6 variables:
Name of the Tarot card.
Raw rank of the card as character.
Suit of the card (wand, coin, cup, sword, or trump).
Type of arcana (minor or major).
Ordered factor indicating the rank within the minor arcana (NA for major arcana).
Integer indicating the rank within the major arcana (0–21, NA for minor arcana).
The dataset is designed for teaching, simulation and modelling purposes, illustrating how heterogeneous ordinal structures can be represented in a statistically consistent way.
The Tarot deck consists of 56 Minor Arcana Cards and 22 Major Arcana Cards.
Since both groups follow different ranking systems, two separate variables are
provided: rank_minor for the ordered structure within the minor arcana
and rank_major for the numeric ordering of the major arcana.
This separation avoids mixing incompatible ordinal scales and makes the dataset suitable for statistical modelling and machine learning applications.
Simulated data.
Other datasets:
Cards,
Pizza,
Roulette,
readCourseData()
head(Tarot) table(Tarot$arcana) summary(Tarot$rank_minor)head(Tarot) table(Tarot$arcana) summary(Tarot$rank_minor)
Sometimes we might wish for the old days be back and want to work with
familiar objects. This function helps to convert tibbles to
data.frames as smoothly as possible.
toBaseR(x, ...) ## S3 method for class 'tbl_df' toBaseR(x, ...) ## S3 method for class 'haven_labelled' toBaseR(x, ...) ## Default S3 method: toBaseR(x, ...)toBaseR(x, ...) ## S3 method for class 'tbl_df' toBaseR(x, ...) ## S3 method for class 'haven_labelled' toBaseR(x, ...) ## Default S3 method: toBaseR(x, ...)
x |
the object to be converted. |
... |
arguments passed on. |
converted object.
Other data.coerce:
as.array.xtabs(),
type-aliases
# a tibble is rolled back to a plain data.frame if (requireNamespace("tibble", quietly = TRUE)) { tbl <- tibble::as_tibble(head(iris)) class(toBaseR(tbl)) } # an object without a method is returned unchanged, with a warning x <- suppressWarnings(toBaseR(1:3)) identical(x, 1:3) # labelled data from other statistical packages: needs 'haven' and # an internet connection, hence the try() if (requireNamespace("haven", quietly = TRUE)) { url <- "http://www.stata.com/videos13/data/webclass.dta" d.webclass <- try(toBaseR(haven::read_dta(url))) }# a tibble is rolled back to a plain data.frame if (requireNamespace("tibble", quietly = TRUE)) { tbl <- tibble::as_tibble(head(iris)) class(toBaseR(tbl)) } # an object without a method is returned unchanged, with a warning x <- suppressWarnings(toBaseR(1:3)) identical(x, 1:3) # labelled data from other statistical packages: needs 'haven' and # an internet connection, hence the try() if (requireNamespace("haven", quietly = TRUE)) { url <- "http://www.stata.com/videos13/data/webclass.dta" d.webclass <- try(toBaseR(haven::read_dta(url))) }
Clean data by means of trimming, i.e., by omitting outlying observations.
trim(x, trim = 0.1, na.rm = FALSE)trim(x, trim = 0.1, na.rm = FALSE)
x |
a numeric vector to be trimmed. |
trim |
the fraction (0 to 0.5) of observations to be trimmed from each
end of x. Values of trim outside that range (and < 1) are taken as the
nearest endpoint. If |
na.rm |
a logical value indicating whether |
A symmetrically trimmed vector x with a fraction of trim observations
(resp. the given number) deleted from each end will be returned. If
trim is set to a value or to an integer value
then the result will be NA. The same applies if
x contains NAs and na.rm is FALSE.
the trimmed vector x. The indices of the trimmed values will
be attached as attribute named "trim".
This function is basically an excerpt from the base function
mean(), which allows the vector x to be trimmed before
calculating the mean.
Other vector.reshape:
setLength(),
vRot(),
vShift()
## generate data set.seed(1234) # for reproducibility x <- rnorm(10) # standard normal x[1] <- x[1] * 10 # introduce outlier ## Trim data x trim(x, trim=0.1) ## Trim fixed number, say cut the 3 extreme elements from each end trim(x, trim=3) ## check function s <- sample(10:20) s.tr <- trim(s, trim = 2) setequal(c(s[attr(s.tr, "trim")], s.tr), s)## generate data set.seed(1234) # for reproducibility x <- rnorm(10) # standard normal x[1] <- x[1] * 10 # introduce outlier ## Trim data x trim(x, trim=0.1) ## Trim fixed number, say cut the 3 extreme elements from each end trim(x, trim=3) ## check function s <- sample(10:20) s.tr <- trim(s, trim = 2) setequal(c(s[attr(s.tr, "trim")], s.tr), s)
Concise aliases for common base R coercion functions.
num(), int(), chr() are direct wrappers around
as.numeric(), as.integer(), and as.character().
nchr() handles the common pitfall of coercing factors to numeric.
bin() converts any two-valued vector to logical.
num(x, ...) int(x, ...) chr(x, ...) nchr(x) bin(x, ...)num(x, ...) int(x, ...) chr(x, ...) nchr(x) bin(x, ...)
x |
a vector. For |
... |
further arguments passed to the underlying base function
( |
num(x, ...)equivalent to as.numeric(x).
int(x, ...)equivalent to as.integer(x).
chr(x, ...)equivalent to as.character(x).
nchr(x)shortcut for as.numeric(as.character(x)).
Avoids the trap of as.numeric(factor) returning internal
integer codes instead of the label values.
bin(x, ...)converts a two-valued vector (character,
factor, integer, or numeric) to logical. Mapping follows
factor() level order: the first level becomes
FALSE, the second TRUE. To reverse, use
!bin(x).
a vector of the target type and the same length as x.
Other data.coerce:
as.array.xtabs(),
toBaseR()
num("3.14") int(3.9) # truncates, does not round chr(1:3) nchr(factor(c("1.5", "2.0", "1.5"))) # correct: 1.5 2.0 1.5 as.numeric(factor(c("1.5", "2.0"))) # wrong: 1 2 bin(c(0L, 1L, 0L, 1L)) bin(c("no", "yes", "no")) # "no" -> FALSE, "yes" -> TRUE !bin(c("no", "yes", "no")) # reversed bin(factor(c("m", "w", "m"))) # "m" -> FALSE, "w" -> TRUEnum("3.14") int(3.9) # truncates, does not round chr(1:3) nchr(factor(c("1.5", "2.0", "1.5"))) # correct: 1.5 2.0 1.5 as.numeric(factor(c("1.5", "2.0"))) # wrong: 1 2 bin(c(0L, 1L, 0L, 1L)) bin(c("no", "yes", "no")) # "no" -> FALSE, "yes" -> TRUE !bin(c("no", "yes", "no")) # reversed bin(factor(c("m", "w", "m"))) # "m" -> FALSE, "w" -> TRUE
Searches a numeric interval for all roots (zeros) of a function f
by subdividing it into n sub-intervals, detecting sign changes, and
refining each candidate with uniroot().
unirootAll( f, interval, lower = min(interval), upper = max(interval), tol = .Machine$double.eps^0.5, maxiter = 1000, n = 100, ... )unirootAll( f, interval, lower = min(interval), upper = max(interval), tol = .Machine$double.eps^0.5, maxiter = 1000, n = 100, ... )
f |
a function for which roots are sought. Must accept a numeric
first argument; additional arguments are passed via |
interval |
a numeric vector of length 2 specifying the search interval.
Either |
lower |
lower bound of the search interval.
Default: |
upper |
upper bound of the search interval.
Default: |
tol |
convergence tolerance passed to |
maxiter |
maximum number of iterations for |
n |
number of sub-intervals used for the initial grid search.
Increase |
... |
additional arguments passed to |
The function f is called as f(x, ...) where x is a
numeric vector. If f does not accept vector input, it is called
element-wise via sapply.
Grid points at which |f(x)| < tol are returned directly as roots.
Sign changes are detected using sign(), which avoids numerical
overflow that can occur with product-based approaches. Non-finite function
values are silently ignored when detecting sign changes. If uniroot
fails on a sub-interval, that interval is skipped with a warning rather
than aborting the entire search.
Limitations: Roots within the same sub-interval of width
(upper - lower) / n may be missed. Roots of even multiplicity
that do not produce a sign change will not be found unless they happen
to fall on a grid point. A warning is issued if no roots are found at
all despite finite function values being present.
a numeric vector of roots found in [lower, upper], sorted in
ascending order. Returns numeric(0) if no roots are found.
stats::uniroot() for the underlying single-root solver.
Other math.basic:
closest(),
crossProd(),
crossProdN(),
dotProd(),
roundTo()
f <- function(x) cos(2 * x)^3 roots <- unirootAll(f, c(0, 10)) stopifnot(all(abs(f(roots)) < 1e-6)) # Non-vectorized function g <- Vectorize(function(x) integrate(function(t) t^x, 0, 1)$value - 0.5) unirootAll(g, c(0.1, 5))f <- function(x) cos(2 * x)^3 roots <- unirootAll(f, c(0, 10)) stopifnot(all(abs(f(roots)) < 1e-6)) # Non-vectorized function g <- Vectorize(function(x) integrate(function(t) t^x, 0, 1)$value - 0.5) unirootAll(g, c(0.1, 5))
Recreates the data.frame out of a contingency table x.
untable(x, ...) ## S3 method for class 'data.frame' untable(x, freq = "Freq", rowNames = NULL, ...) ## Default S3 method: untable(x, dimnames = NULL, type = NULL, rowNames = NULL, colNames = NULL, ...)untable(x, ...) ## S3 method for class 'data.frame' untable(x, freq = "Freq", rowNames = NULL, ...) ## Default S3 method: untable(x, dimnames = NULL, type = NULL, rowNames = NULL, colNames = NULL, ...)
x |
a numeric vector, a matrix, a table or a data.frame. If x is a
vector, a matrix or a table it is interpreted as frequencies which are to be
inflated to the original list. |
... |
further arguments passed to or from functions (not used here). |
freq |
character, the name of the frequency variable in case x is a data.frame. |
rowNames |
a names vector for the rownames of the resulting data.frame
If set to |
dimnames |
the dimension names of x to be used for expanding. Can be
used to expand a weight vector to its original values. If set to |
type |
defines the data type generated. This allows to directly define factors or ordered factors, but also numeric values. See examples. |
colNames |
a names vector for the colnames of the resulting data.frame
If set to |
For x being a vector this reduces to rep(..., n) with n as vector
(which is not supported by rep()). NAs in the table will be
treated as 0 without raising an error.
a data.frame with the detailed data (even if x was a 1-dimensional table).
expand.grid(), rep(), gl(),
xtabs()
Other data.reshape:
collapseTable(),
long-wide-reshape,
splitAt(),
splitX()
d.titanic <- untable(Titanic) str(d.titanic) # ... not the same as: data.frame(Titanic) tab <- table(set1=sample(letters[1:5], size=40, replace=TRUE), set2=sample(letters[11:15], size=40, replace=TRUE)) untable(tab) # return a numeric vector by setting type and coerce to a vector by [,] untable(c(6,2,2), type="as.numeric")[,] # how to produce the original list based on frequencies, given as a data.frame d.freq <- data.frame(xtabs(Freq ~ Sex + Survived, data=Titanic)) # a data list with each individual d.data <- untable( xtabs(c(1364, 126, 367, 344) ~ ., expand.grid(levels(d.freq$Sex),levels(d.freq$Survived)))) head(d.data) # expand a weights vector untable(c(1,4,5), dimnames=list(c("Zurich","Berlin","London"))) # and the same with a numeric vector untable(c(1,4,5), dimnames=list(c(5,10,15)), type="as.numeric")[,] # ... which again is nothing else than rep(times=c(1,4,5), x=c(5,10,15)) # the data.frame interface d.freq <- data.frame(f1=c("A","A","B","B"), f2=c("C","D","C","D"), Freq=c(1,2,3,4)) untable(d.freq)d.titanic <- untable(Titanic) str(d.titanic) # ... not the same as: data.frame(Titanic) tab <- table(set1=sample(letters[1:5], size=40, replace=TRUE), set2=sample(letters[11:15], size=40, replace=TRUE)) untable(tab) # return a numeric vector by setting type and coerce to a vector by [,] untable(c(6,2,2), type="as.numeric")[,] # how to produce the original list based on frequencies, given as a data.frame d.freq <- data.frame(xtabs(Freq ~ Sex + Survived, data=Titanic)) # a data list with each individual d.data <- untable( xtabs(c(1364, 126, 367, 344) ~ ., expand.grid(levels(d.freq$Sex),levels(d.freq$Survived)))) head(d.data) # expand a weights vector untable(c(1,4,5), dimnames=list(c("Zurich","Berlin","London"))) # and the same with a numeric vector untable(c(1,4,5), dimnames=list(c(5,10,15)), type="as.numeric")[,] # ... which again is nothing else than rep(times=c(1,4,5), x=c(5,10,15)) # the data.frame interface d.freq <- data.frame(f1=c("A","A","B","B"), f2=c("C","D","C","D"), Freq=c(1,2,3,4)) untable(d.freq)
Reconstructs the TRUE positions from the index vector returned
by which(), producing a logical vector of length n.
Note that this is not a perfect inverse: which() discards
NA and FALSE positions, so the original vector cannot be
fully recovered.
unwhich( idx, n = if (length(idx) > 0L && !anyNA(idx) && all(idx > 0L)) max(idx) else 0L, useNames = TRUE )unwhich( idx, n = if (length(idx) > 0L && !anyNA(idx) && all(idx > 0L)) max(idx) else 0L, useNames = TRUE )
idx |
a vector of non-zero whole-number indices. Positive
values mark |
n |
a single non-negative whole number giving the length of
the result. For positive |
useNames |
logical. If |
Negative indices follow standard R semantics: unwhich(-2, 5)
returns a vector with TRUE everywhere except position 2.
Positive and negative indices must not be mixed.
a logical vector of length n.
The positive-index construction (rv[indices] <- TRUE with name
propagation) is based on code by Nick Sabbe; negative-index handling
and input validation are original additions.
Sabbe, N. (2012). Inverse of which.
https://stackoverflow.com/questions/7659833/inverse-of-which
Other vector.utils:
nz()
ll <- c(TRUE, FALSE, TRUE, NA, FALSE, FALSE, TRUE) names(ll) <- letters[seq_along(ll)] i <- which(ll) # reconstruct TRUE positions (names preserved on TRUE positions) unwhich(i, length(ll)) # without names unwhich(i, length(ll), useNames = FALSE) # negative index: TRUE everywhere except position 2 unwhich(-2, 5) # empty index -> all-FALSE vector unwhich(integer(0), n = 5L)ll <- c(TRUE, FALSE, TRUE, NA, FALSE, FALSE, TRUE) names(ll) <- letters[seq_along(ll)] i <- which(ll) # reconstruct TRUE positions (names preserved on TRUE positions) unwhich(i, length(ll)) # without names unwhich(i, length(ll), useNames = FALSE) # negative index: TRUE everywhere except position 2 unwhich(-2, 5) # empty index -> all-FALSE vector unwhich(integer(0), n = 5L)
Performs an HTTP request to determine whether a resource exists at a given URL.
Uses a HEAD request by default and falls back to GET if necessary.
urlExists(url, timeout = 5)urlExists(url, timeout = 5)
url |
character string. The full URL to check. |
timeout |
numeric. Timeout in seconds for the HTTP request. Default is 5. |
The function first sends an HTTP HEAD request to minimize data transfer.
If the server responds with a status indicating that HEAD itself is not
supported (403, 405, 501), a GET request is attempted as a fallback. A
plain 404 is taken at face value, so that non-existing files do not trigger a
second request.
If the request fails (e.g., due to network issues or invalid URLs), the function
returns FALSE and stores the error message as an attribute.
logical value indicating whether the resource exists (TRUE) or not (FALSE).
The returned value has additional attributes:
status: HTTP status code returned by the server (e.g. 200, 404).
error: error message (if a request error occurred).
Other file.path:
buildPath(),
findDownload(),
isFilePath(),
isUrl(),
splitPath()
# needs an internet connection; an unreachable host is reported # through the attributes rather than by an error urlExists("https://www.example.com/data.csv") res <- urlExists("https://invalid-url.test/file.csv") attr(res, "status") attr(res, "error")# needs an internet connection; an unreachable host is reported # through the attributes rather than by an error urlExists("https://www.example.com/data.csv") res <- urlExists("https://invalid-url.test/file.csv") attr(res, "status") attr(res, "error")
Rotates a vector cyclically to the right by k positions.
Negative values of k rotate to the left.
vRot(x, k = 1L)vRot(x, k = 1L)
x |
a vector. |
k |
integer. Number of positions to rotate (default = 1). |
The rotation is cyclic, meaning elements shifted off one end reappear on the other.
a vector of the same length as x, rotated cyclically.
Other vector.reshape:
setLength(),
trim(),
vShift()
vRot(1:5, 2) # 4 5 1 2 3 vRot(1:5, -1) # 2 3 4 5 1vRot(1:5, 2) # 4 5 1 2 3 vRot(1:5, -1) # 2 3 4 5 1
Shifts a vector to the left or right by k positions.
Vacated positions are filled with NA.
vShift(x, k = 1L)vShift(x, k = 1L)
x |
a vector. |
k |
integer. Number of positions to shift. Positive values shift to the right, negative values to the left. |
Unlike vRot(), this function does not wrap elements around.
Elements shifted beyond the vector bounds are discarded.
a vector of the same length as x, shifted with NA padding.
Other vector.reshape:
setLength(),
trim(),
vRot()
vShift(1:5, 2) # NA NA 1 2 3 vShift(1:5, -2) # 3 4 5 NA NA vShift(1:5, 10) # NA NA NA NA NAvShift(1:5, 2) # NA NA 1 2 3 vShift(1:5, -2) # 3 4 5 NA NA vShift(1:5, 10) # NA NA NA NA NA
Winsorization replaces extreme values in a numeric vector by less extreme, predefined bounds. Values below a lower limit are set to that limit, and values above an upper limit are set to that upper limit.
winsorize(x, limits = quantile(x, probs = c(0.05, 0.95), na.rm = TRUE))winsorize(x, limits = quantile(x, probs = c(0.05, 0.95), na.rm = TRUE))
x |
a numeric vector to be winsorized. |
limits |
a numeric vector of length two specifying the lower and upper
winsorization limits. Defaults to the 5% and 95% quantiles of |
By default, the limits are defined as the 5% and 95% quantiles of the data. Missing values are ignored when computing quantiles and are preserved in the output.
Formally, the winsorized vector is defined as:
where and denote the lower and upper bounds.
The argument limits allows full control over the limits. It can be:
A numeric vector of length two specifying fixed bounds
The result of a call to quantile() (e.g. with custom type)
Winsorization is commonly used in robust statistics to reduce the influence
of outliers. In some cases, it can be beneficial to standardize the data
(e.g., using scale()) before applying winsorization.
a numeric vector of the same length as x, where:
values below the lower limit are replaced by the lower limit.
values above the upper limit are replaced by the upper limit.
missing values remain unchanged.
DescToolsX::scaleX(), robustHD::winsorize()
Other math.transform:
linScale(),
logit(),
percentRank(),
rankX()
set.seed(9128) x <- c(rnorm(10), NA, -100, 100) # Default winsorization (5% / 95% quantiles) winsorize(x) # Winsorization using fixed bounds winsorize(x, limits = c(-10, 10)) # Custom quantile definition winsorize(x, limits = quantile(x, c(0.1, 0.9), type = 1, na.rm = TRUE)) # One-sided winsorization winsorize(x, limits = c(-Inf, 2)) # upper bound only winsorize(x, limits = c(-2, Inf)) # lower bound onlyset.seed(9128) x <- c(rnorm(10), NA, -100, 100) # Default winsorization (5% / 95% quantiles) winsorize(x) # Winsorization using fixed bounds winsorize(x, limits = c(-10, 10)) # Custom quantile definition winsorize(x, limits = quantile(x, c(0.1, 0.9), type = 1, na.rm = TRUE)) # One-sided winsorization winsorize(x, limits = c(-Inf, 2)) # upper bound only winsorize(x, limits = c(-2, Inf)) # lower bound only
Sets the random seed for the duration of expr and restores the
caller's random state afterwards. This makes a single result
reproducible without hijacking the random stream of the surrounding
script: two calls with the same seed give the same result, and whatever
is drawn after them is unaffected by either.
withSeed(seed, expr)withSeed(seed, expr)
seed |
a single number, or |
expr |
the expression to evaluate; evaluated lazily, in the caller's environment |
The plain idiom set.seed(s); expr lacks the second half. In a
script that generates a series of random objects, seeding one of them
shifts every draw that follows, so results that were correct before the
seed was added silently change.
the value of expr
set.seed(1) a <- runif(1) set.seed(1) withSeed(99, runif(1)) # unrelated draw in between identical(runif(1), a) # the stream continued as if it never happened identical(withSeed(7, runif(3)), withSeed(7, runif(3)))set.seed(1) a <- runif(1) set.seed(1) withSeed(99, runif(1)) # unrelated draw in between identical(runif(1), a) # the stream continued as if it never happened identical(withSeed(7, runif(3)), withSeed(7, runif(3)))