Title: | Functions and Utilities for Jordan |
---|---|
Description: | Provides core functions and utilities for packages and other code developed by Jordan Mark Barbone. |
Authors: | Jordan Mark Barbone [aut, cph, cre] |
Maintainer: | Jordan Mark Barbone <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.2.1.9003 |
Built: | 2024-11-07 05:42:47 UTC |
Source: | https://github.com/jmbarbone/fuj |
Arithmetic wrappers
See base::Arithmetic
add(7, 2) # + subtract(7, 2) # - multiply(7, 2) # * divide(7, 2) # / raise_power(7, 2) # ^ remainder(7, 2) # %% divide_int(7, 2) # %/%
add(7, 2) # + subtract(7, 2) # - multiply(7, 2) # * divide(7, 2) # / raise_power(7, 2) # ^ remainder(7, 2) # %% divide_int(7, 2) # %/%
Extract and replace aliases
See base::Extract
df <- quick_dfl(a = 1:5, b = 6:10) # alias of `[` subset1(df, 1) subset1(df, 1, ) subset1(df, , 1) subset1(df, , 1, drop = FALSE) # alias of `[[` subset2(df, 1) subset2(df, 1, 2) # alias of `$` subset3(df, a) subset3(df, "b") subset3(df, "foo") # alias of `[<-` subassign1(df, "a", , 2)
df <- quick_dfl(a = 1:5, b = 6:10) # alias of `[` subset1(df, 1) subset1(df, 1, ) subset1(df, , 1) subset1(df, , 1, drop = FALSE) # alias of `[[` subset2(df, 1) subset2(df, 1, 2) # alias of `$` subset3(df, a) subset3(df, "b") subset3(df, "foo") # alias of `[<-` subassign1(df, "a", , 2)
Simple wrapper for concatenating strings
collapse(..., sep = "")
collapse(..., sep = "")
... |
one or more R objects, to be converted to character vectors. |
sep |
a character string to separate the terms. Not
|
A character
vector of concatenated values. See base::paste for
more details.
collapse(1:10) collapse(list("a", b = 1:2)) collapse(quick_dfl(a = 1:3, b = 4:6), sep = "-")
collapse(1:10) collapse(list("a", b = 1:2)) collapse(quick_dfl(a = 1:3, b = 4:6), sep = "-")
Get an object from a namespace
package %::% name package %:::% name package %colons% name
package %::% name package %:::% name package %colons% name
package |
Name of the package |
name |
Name to retrieve |
The functions mimic the use of ::
and :::
for extracting values
from namespaces. %colons%
is an alias for %::%
.
The variable name
from package package
To reiterate from other documentation: it is not advised to
use :::
in your code as it will retrieve non-exported objects that may be
more likely to change in their functionality that exported objects.
help("::")
identical("base" %::% "mean", base::mean) "fuj" %:::% "colons_example" # unexported value
identical("base" %::% "mean", base::mean) "fuj" %:::% "colons_example" # unexported value
Get the exact attributes of an object
exattr(x, which) x %attr% which
exattr(x, which) x %attr% which
x |
an object whose attributes are to be accessed. |
which |
a non-empty character string specifying which attribute is to be accessed. |
See base::attr
foo <- struct(list(), "foo", aa = TRUE) attr(foo, "a") # TRUE : partial match successful exattr(foo, "a") # NULL : partial match failed exattr(foo, "aa") # TRUE : exact match
foo <- struct(list(), "foo", aa = TRUE) attr(foo, "a") # TRUE : partial match successful exattr(foo, "a") # NULL : partial match failed exattr(foo, "aa") # TRUE : exact match
Flip an object.
flip(x, ...) ## Default S3 method: flip(x, ...) ## S3 method for class 'matrix' flip(x, by = c("rows", "columns"), keep_rownames = NULL, ...) ## S3 method for class 'data.frame' flip(x, by = c("rows", "columns"), keep_rownames = NULL, ...)
flip(x, ...) ## Default S3 method: flip(x, ...) ## S3 method for class 'matrix' flip(x, by = c("rows", "columns"), keep_rownames = NULL, ...) ## S3 method for class 'data.frame' flip(x, by = c("rows", "columns"), keep_rownames = NULL, ...)
x |
An object |
... |
Additional arguments passed to methods |
by |
Flip by |
keep_rownames |
Logical, if |
A vector
of values, equal length of x
that is reversed or a
data frame
with flipped rows/columns
flip(letters[1:3]) flip(seq.int(9, -9, by = -3)) flip(head(iris)) flip(head(iris), keep_rownames = TRUE) flip(head(iris), by = "col")
flip(letters[1:3]) flip(seq.int(9, -9, by = -3)) flip(head(iris)) flip(head(iris), keep_rownames = TRUE) flip(head(iris), by = "col")
is_path()
checks for either a file_path
class or an
fs_path
, the latter useful for the fs
package.
file_path()
is an alias for fp()
and is_file_path()
is an alias for
is_path()
.
fp(...) file_path(...) is_path(x) is_file_path(x)
fp(...) file_path(...) is_path(x) is_file_path(x)
... |
Path components, passed to |
x |
An object to test |
Lightweight file path functions
fp()
/file_path()
: A character
vector of the normalized path with a
"file_path"
class
is_path()
/is_file_path()
: A TRUE
or FALSE
value
fp("here") fp("~/there") fp("back\\slash") fp("remove//extra\\\\slashes") fp("a", c("b", "c"), "d")
fp("here") fp("~/there") fp("back\\slash") fp("remove//extra\\\\slashes") fp("a", c("b", "c"), "d")
NULL
or no lengthReplace if NULL
or not length
x %||% y x %|||% y x %len% y
x %||% y x %|||% y x %len% y
x , y
|
If |
A mostly copy of rlang
's %||%
except does not use rlang::is_null()
,
which, currently, calls the same primitive base::is.null function.
Note: %||%
is copied from {base}
if available (R versions >= 4.4)
x
if it is not NULL
or has length, depending on check
# replace NULL (for R < 4.4) NULL %||% 1L 2L %||% 1L # replace empty "" %|||% 1L NA %|||% 1L double() %|||% 1L NULL %|||% 1L # replace no length logical() %len% TRUE FALSE %len% TRUE
# replace NULL (for R < 4.4) NULL %||% 1L 2L %||% 1L # replace empty "" %|||% 1L NA %|||% 1L double() %|||% 1L NULL %|||% 1L # replace no length logical() %len% TRUE FALSE %len% TRUE
include()
checks whether or not the namespace has been loaded
to the base::search()
path. It uses the naming convention
include:{package}
to denote the differences from loading via
base::library()
or base::require()
. When exports
is NULL
, the
environment is detached from the search path if found. When exports
is
not NULL
,
Note: This function has the specific purpose of affecting the search
path. Use options(fuj.verbose = TRUE)
or options(verbose = TRUE)
for
more information.
include(package, exports = NULL, lib = .libPaths(), pos = 2L, warn = NULL)
include(package, exports = NULL, lib = .libPaths(), pos = 2L, warn = NULL)
package |
A package name. This can be given as a name or a character
string. See section |
exports |
A character vector of exports. When named, these exports will be aliases as such. |
lib |
See |
pos |
An integer specifying the position in the |
warn |
See |
Include (attach) a package and specific exports to Search Path
The attached environment, invisibly.
package
class handlingWhen package
is a name or AsIs,
assumed an installed package. When package
is a file path (via
is_path()
) then package
is assumed a file path. When just a string, a
viable path is checked first; if it doesn't exist, then it is assumed a
package.
When the package is source()
'd the name of the environment defaults to
the base name of x
(file extension removed). However, if the object
.AttachName
is found in the sourced file, then that is used as the
environment name for the search()
path.
Note: include()
won't try to attach an environment a second time,
however, when package
is a path, it must be source()
ed each time to
check for the .AttachName
object. If there are any side effects, they
will be repeated each time include(path)
is called.
# include(package) will ensure that the entire package is attached include(fuj) head(ls("include:fuj"), 20) detach("include:fuj", character.only = TRUE) # include a single export include(fuj, "collapse") # include multiple exports, and alias include(fuj, c( no_names = "remove_names", match_any = "any_match" )) # include an export where the alias has a warn conflict include(fuj, c(attr = "exattr")) # note that all 4 exports are included ls("include:fuj") # all exports are the same identical(collapse, fuj::collapse) identical(no_names, fuj::remove_names) identical(match_any, fuj::any_match) identical(attr, fuj::exattr)
# include(package) will ensure that the entire package is attached include(fuj) head(ls("include:fuj"), 20) detach("include:fuj", character.only = TRUE) # include a single export include(fuj, "collapse") # include multiple exports, and alias include(fuj, c( no_names = "remove_names", match_any = "any_match" )) # include an export where the alias has a warn conflict include(fuj, c(attr = "exattr")) # note that all 4 exports are included ls("include:fuj") # all exports are the same identical(collapse, fuj::collapse) identical(no_names, fuj::remove_names) identical(match_any, fuj::any_match) identical(attr, fuj::exattr)
Tries to not complain about empty arguments
list0(...) lst(...)
list0(...) lst(...)
... |
Arguments to collect in a list |
A list
of ...
try(list(1, )) list0(1, ) try(list(a = 1, )) list0(a = 1, ) try(list(a = 1, , c = 3, )) list0(a = 1, , c = 3, )
try(list(1, )) list0(1, ) try(list(a = 1, )) list0(a = 1, ) try(list(a = 1, , c = 3, )) list0(a = 1, , c = 3, )
Non matching alternatives and supplementary functions.
is_in(x, table) is_out(x, table) x %out% table is_within(x, table) x %wi% table is_without(x, table) x %wo% table no_match(x, table) any_match(x, table)
is_in(x, table) is_out(x, table) x %out% table is_within(x, table) x %wi% table is_without(x, table) x %wo% table no_match(x, table) any_match(x, table)
x |
vector or |
table |
vector or |
Contrast with base::match()
, base::intersect()
, and
base::%in%()
The functions of %wi%
and %wo%
can be used in lieu of
base::intersect()
and base::setdiff()
. The primary difference is that
the base functions return only unique values, which may not be a desired
behavior.
%out%
: A logical
vector of equal length of x
, table
%wo%
, %wi%
: A vector of values of x
any_match()
, no_match()
: TRUE
or FALSE
is_in()
: see base::%in%()
1:10 %in% c(1, 3, 5, 9) 1:10 %out% c(1, 3, 5, 9) letters[1:5] %wo% letters[3:7] letters[1:5] %wi% letters[3:7] # base functions only return unique values c(1:6, 7:2) %wo% c(3, 7, 12) # -> keeps duplicates setdiff(c(1:6, 7:2), c(3, 7, 12)) # -> unique values c(1:6, 7:2) %wi% c(3, 7, 12) # -> keeps duplicates intersect(c(1:6, 7:2), c(3, 7, 12)) # -> unique values
1:10 %in% c(1, 3, 5, 9) 1:10 %out% c(1, 3, 5, 9) letters[1:5] %wo% letters[3:7] letters[1:5] %wi% letters[3:7] # base functions only return unique values c(1:6, 7:2) %wo% c(3, 7, 12) # -> keeps duplicates setdiff(c(1:6, 7:2), c(3, 7, 12)) # -> unique values c(1:6, 7:2) %wi% c(3, 7, 12) # -> keeps duplicates intersect(c(1:6, 7:2), c(3, 7, 12)) # -> unique values
Aliases for base::suppressMessages()
and base::suppressWarnings()
muffle(expr, fun, classes = "message") wuffle(expr, fun, classes = "warning")
muffle(expr, fun, classes = "message") wuffle(expr, fun, classes = "warning")
expr |
An expression to evaluate |
fun |
A function to muffle (or wuffle) |
classes |
A character vector if classes to suppress |
The result of expr
or a function
wrapping fun
# load function foo <- function(...) { message("You entered :", paste0(...)) c(...) } # wrap around function or muffle the function ti's muffle(foo(1, 2)) muffle(fun = foo)(1, 2) sapply(1:3, muffle(fun = foo)) # silence warnings wuffle(as.integer("a")) sapply(list(1, "a", "0", ".2"), wuffle(fun = as.integer))
# load function foo <- function(...) { message("You entered :", paste0(...)) c(...) } # wrap around function or muffle the function ti's muffle(foo(1, 2)) muffle(fun = foo)(1, 2) sapply(1:3, muffle(fun = foo)) # silence warnings wuffle(as.integer("a")) sapply(list(1, "a", "0", ".2"), wuffle(fun = as.integer))
Sets or removes names
set_names(x, nm = x) remove_names(x) x %names% nm is_named(x, zero_ok = TRUE)
set_names(x, nm = x) remove_names(x) x %names% nm is_named(x, zero_ok = TRUE)
x |
A vector of values |
nm |
A vector of names |
zero_ok |
If |
x
with nm
values assigned to names (if x
is NULL
, NULL
is
returned)
set_names(1:5) set_names(1:5, c("a", "b", "c", "d", "e")) x <- c(a = 1, b = 2) remove_names(x) x %names% c("c", "d") is_named(x)
set_names(1:5) set_names(1:5, c("a", "b", "c", "d", "e")) x <- c(a = 1, b = 2) remove_names(x) x %names% c("c", "d") is_named(x)
Template for a new condition. See more at base::conditions
new_condition( msg = "", class = NULL, call = NULL, type = c("error", "warning", NA_character_), message = msg, pkg = package() )
new_condition( msg = "", class = NULL, call = NULL, type = c("error", "warning", NA_character_), message = msg, pkg = package() )
msg , message
|
A message to print |
class |
Character string of a single condition class |
call |
A call expression |
type |
The type (additional class) of condition: either |
pkg |
Control or adding package name to condition. If |
The use of .packageName
when pkg = TRUE
may not be valid during
active development. When the attempt to retrieve the .packageName
object
is unsuccessful, the error is quietly ignored. However, this should be
successful once the package is build and functions can then utilize this
created object.
A condition
with the classes specified from class
and type
# empty condition x <- new_condition("informative error message", class = "foo") try(stop(x)) # with pkg x <- new_condition("msg", class = "foo", pkg = "bar") # class contains multiple identifiers, including a "bar:fooError" class(x) # message contains package information at the end try(stop(x))
# empty condition x <- new_condition("informative error message", class = "foo") try(stop(x)) # with pkg x <- new_condition("msg", class = "foo", pkg = "bar") # class contains multiple identifiers, including a "bar:fooError" class(x) # message contains package information at the end try(stop(x))
Determine operating systems
is_windows() is_macos() is_linux()
is_windows() is_macos() is_linux()
TRUE
or FALSE
is_windows() is_macos() is_linux()
is_windows() is_macos() is_linux()
This is a speedier implementation of as.data.frame()
but does not provide
the same sort of checks. It should be used with caution.
quick_df(x = NULL) empty_df() quick_dfl(...)
quick_df(x = NULL) empty_df() quick_dfl(...)
x |
A list or |
... |
Columns as |
A data.frame
; if x
is NULL
a data.frame
with 0
rows and 0
columns is returned (similar to calling data.frame()
but faster).
empty_df()
returns a data.frame
with 0
rows and 0
columns.
# unnamed will use make.names() x <- list(1:10, letters[1:10]) quick_df(x) # named is preferred names(x) <- c("numbers", "letters") quick_df(x) # empty data.frame empty_df() # or quick_df(NULL)
# unnamed will use make.names() x <- list(1:10, letters[1:10]) quick_df(x) # named is preferred names(x) <- c("numbers", "letters") quick_df(x) # empty data.frame empty_df() # or quick_df(NULL)
Require namespace
require_namespace(package, ...)
require_namespace(package, ...)
package , ...
|
Package names |
TRUE
(invisibly) if found; otherwise errors
isTRUE(require_namespace("base")) # returns invisibly try(require_namespace("1package")) # (using a purposefully bad name) require_namespace("base", "utils") try(require_namespace("base>=3.5", "utils>4.0", "fuj==10.0"))
isTRUE(require_namespace("base")) # returns invisibly try(require_namespace("1package")) # (using a purposefully bad name) require_namespace("base", "utils") try(require_namespace("base>=3.5", "utils>4.0", "fuj==10.0"))
Create simple structures
struct(x, class, ..., .keep_attr = FALSE)
struct(x, class, ..., .keep_attr = FALSE)
x |
An object; if |
class |
A vector of classes; can also be |
... |
Named attributes to set to |
.keep_attr |
Control for keeping attributes from |
Unlike base::structure()
this does not provide additional checks
for special names, performs no base::storage.mode()
conversions for
factors
(x
therefor has to be an integer
), attributes
from x
are
not retained, and class
is specified outside of other attributes and
assigned after base::attributes()
is called.
Essentially, this is just a wrapper for calling base::attributes()
then
base::class()
.
Note that base::structure()
provides a warning when the first argument is
NULL
. struct()
does not. The coercion from NULL
to list()
is
done, and documented, in base::attributes()
.
An object with class defined as class
and attributes ...
x <- list(a = 1, b = 2) # structure() retains the $names attribute of x but struct() does not structure(x, class = "data.frame", row.names = 1L) struct(x, "data.frame", row.names = 1L) struct(x, "data.frame", row.names = 1L, names = names(x)) # structure() corrects entries for "factor" class # but struct() demands the data to be an integer structure(1, class = "factor", levels = "a") try(struct(1, "factor", levels = "a")) struct(1L, "factor", levels = "a") # When first argument is NULL -- attributes() coerces try(structure(NULL)) # NULL, no call to attributes() struct(NULL, NULL) # list(), without warning x <- NULL attributes(x) <- NULL x # NULL attributes(x) <- list() # struct() always grabs ... into a list x # list() # Due to the use of class() to assign class, you may experience some # other differences between structure() and struct() x <- structure(1, class = "integer") y <- struct(1, "integer") str(x) str(y) all.equal(x, y) # Be careful about carrying over attributes x <- quick_df(list(a = 1:2, b = 3:4)) # returns empty data.frame struct(x, "data.frame", new = 1) # safely changing names without breaking rownames struct(x, "data.frame", names = c("c", "d")) # breaks struct(x, "data.frame", names = c("c", "d"), .keep_attr = TRUE) struct(x, "data.frame", names = c("c", "d"), .keep_attr = "row.names") # safely adds comments struct(x, "data.frame", comment = "hi", .keep_attr = TRUE) struct(x, "data.frame", comment = "hi", .keep_attr = c("names", "row.names")) # assignment in ... overwrites attributes struct(x, "data.frame", names = c("var1", "var2"), .keep_attr = TRUE)
x <- list(a = 1, b = 2) # structure() retains the $names attribute of x but struct() does not structure(x, class = "data.frame", row.names = 1L) struct(x, "data.frame", row.names = 1L) struct(x, "data.frame", row.names = 1L, names = names(x)) # structure() corrects entries for "factor" class # but struct() demands the data to be an integer structure(1, class = "factor", levels = "a") try(struct(1, "factor", levels = "a")) struct(1L, "factor", levels = "a") # When first argument is NULL -- attributes() coerces try(structure(NULL)) # NULL, no call to attributes() struct(NULL, NULL) # list(), without warning x <- NULL attributes(x) <- NULL x # NULL attributes(x) <- list() # struct() always grabs ... into a list x # list() # Due to the use of class() to assign class, you may experience some # other differences between structure() and struct() x <- structure(1, class = "integer") y <- struct(1, "integer") str(x) str(y) all.equal(x, y) # Be careful about carrying over attributes x <- quick_df(list(a = 1:2, b = 3:4)) # returns empty data.frame struct(x, "data.frame", new = 1) # safely changing names without breaking rownames struct(x, "data.frame", names = c("c", "d")) # breaks struct(x, "data.frame", names = c("c", "d"), .keep_attr = TRUE) struct(x, "data.frame", names = c("c", "d"), .keep_attr = "row.names") # safely adds comments struct(x, "data.frame", comment = "hi", .keep_attr = TRUE) struct(x, "data.frame", comment = "hi", .keep_attr = c("names", "row.names")) # assignment in ... overwrites attributes struct(x, "data.frame", names = c("var1", "var2"), .keep_attr = TRUE)
Simple verbose condition handling
verbose( ..., .fill = getOption("fuj.verbose.fill"), .label = getOption("fuj.verbose.label"), .verbose = getOption("fuj.verbose", getOption("verbose")) ) make_verbose(opt)
verbose( ..., .fill = getOption("fuj.verbose.fill"), .label = getOption("fuj.verbose.label"), .verbose = getOption("fuj.verbose", getOption("verbose")) ) make_verbose(opt)
... |
A message to display. When |
.fill |
When |
.label |
A label to prefix the message with (controlled through
|
.verbose |
When |
opt |
An option to use in lieu of |
verbose()
can be safely placed in scripts to signal additional
message conditions. verbose()
can be controlled with
options("verbose")
(the default) and an override,
options("fuj.verbose")
. The latter can be set to a function whose result
will be used for conditional evaluation.
make_verbose()
allows for the creation of a custom verbose function.
None, called for its side-effects. When conditions are met, will
signal a verboseMessage
condition.
op <- options(verbose = FALSE) verbose("will not show") options(verbose = TRUE) verbose("message printed") verbose("multiple lines ", "will be ", "combined") options(op) op <- options(fuj.verbose = function() TRUE) verbose("function will evaluate") verbose(NULL) # nothing verbose(NULL, "something") verbose(if (FALSE) { "`if` returns `NULL` when not `TRUE`, which makes for additional control" }) options(op) # make your own verbose verb <- make_verbose("fuj.foo.bar") verb("will not show") options(fuj.foo.bar = TRUE) verb("will show")
op <- options(verbose = FALSE) verbose("will not show") options(verbose = TRUE) verbose("message printed") verbose("multiple lines ", "will be ", "combined") options(op) op <- options(fuj.verbose = function() TRUE) verbose("function will evaluate") verbose(NULL) # nothing verbose(NULL, "something") verbose(if (FALSE) { "`if` returns `NULL` when not `TRUE`, which makes for additional control" }) options(op) # make your own verbose verb <- make_verbose("fuj.foo.bar") verb("will not show") options(fuj.foo.bar = TRUE) verb("will show")
Prompts the user to make a yes/no selection
yes_no(..., na = NULL, n_yes = 1, n_no = 2, noninteractive_error = TRUE)
yes_no(..., na = NULL, n_yes = 1, n_no = 2, noninteractive_error = TRUE)
... |
text to display |
na |
Text for an NA response. When NULL, will not provide a possible NA response. When |
n_yes , n_no
|
The number of yes/no selections |
noninteractive_error |
While |