Nothing
#' Joining verbs
#'
#' Two-table joins. Check the
#' ["Joining verbs" vignette](https://asardaes.github.io/table.express/articles/joins.html) for more
#' information.
#'
#' @rdname joins
#' @name joins
#'
#' @param x An [ExprBuilder] instance.
#' @param y A [data.table::data.table-class] or, for some verbs (see details), a call to
#' [nest_expr()].
#' @param ... Expressions for the `on` part of the join.
#' @param nomatch,mult,roll,rollends See [data.table::data.table].
#' @param .parent_env See [end_expr()].
#' @param .SDcols For `mutate_join`. See the details below.
#' @param sort Passed to [data.table::merge].
#' @param allow Passed as [`data.table`][data.table::data.table]'s `allow.cartesian`.
#' @param .by_each For `mutate_join`. See the details below.
#' @template expr-arg
#' @param .selecting One or more expressions, possibly contained in a call to `list` or `.`, that
#' will be added to `j` in the same frame as the join.
#' @param .framing Similar to `.selecting`, but added to the frame with [frame_append()].
#' @param .to_eager Internal, should be left as `FALSE` in all external calls.
#'
#' @details
#'
#' The following joins support [nest_expr()] in `y`:
#'
#' - `anti_join`
#' - `inner_join`
#' - `right_join`
#'
#' @seealso
#'
#' [data.table::data.table], [dplyr::join]
#'
#' @examples
#'
#' lhs <- data.table::data.table(x = rep(c("b", "a", "c"), each = 3),
#' y = c(1, 3, 6),
#' v = 1:9)
#'
#' rhs <- data.table::data.table(x = c("c", "b"),
#' v = 8:7,
#' foo = c(4, 2))
#'
NULL
#' @importFrom rlang as_string
#' @importFrom rlang syms
#'
name_switcheroo <- function(on) {
chars <- unname(sapply(on, rlang::as_string))
nms <- names(on)
empty_names <- !nzchar(nms)
if (any(empty_names)) {
nms[empty_names] <- chars[empty_names]
}
names(nms) <- chars
names(nms)[empty_names] <- ""
rlang::syms(nms)
}
#' @importFrom rlang abort
#' @importFrom rlang call2
#' @importFrom rlang call_args
#' @importFrom rlang call_name
#'
comp_switcheroo <- function(on) {
lapply(unname(on), function(e) {
comp <- switch(rlang::call_name(e),
"==" = "==",
"<" = ">",
"<=" = ">=",
">" = "<",
">=" = "<=",
# default
rlang::abort("The 'on' expressions must be variables or comparisons."))
args <- rev(rlang::call_args(e))
rlang::call2(comp, !!!args)
})
}
#' @importFrom rlang is_call
#'
name_comp_switcheroo <- function(on) {
if (length(on) == 0L) {
return(on)
}
calls <- sapply(on, rlang::is_call)
non_calls <- !calls
ans <- structure(rep(list(NULL), length(on)),
names = rep("", length(on)))
ans[calls] <- comp_switcheroo(on[calls])
if (any(non_calls)) {
switched_names <- name_switcheroo(on[non_calls])
ans[non_calls] <- switched_names
names(ans)[non_calls] <- names(switched_names)
}
ans
}
#' @importFrom rlang is_call
#' @importFrom rlang is_missing
#' @importFrom rlang warn
#'
leftright_join <- function(eb, on, join_extras) {
calls <- sapply(on, rlang::is_call)
which_missing <- sapply(join_extras, rlang::is_missing)
if (!which_missing[1L] && is.null(join_extras$nomatch) && all(which_missing[-1L]) && all(!calls)) {
rlang::warn("Specifying 'nomatch = NULL' but none of ['mult', 'roll', 'rollends'] is equivalent to an inner join.")
}
if (length(on) > 0L) {
frame_append(eb, on = list(!!!on))
}
frame_append(eb, !!!join_extras, .ignore_empty = "all")
}
#' @importFrom rlang enquos
#' @importFrom rlang is_call
#' @importFrom rlang is_character
#'
assume_dplyr_join <- function(...) {
dots <- parse_dots(FALSE, ...)
quoted_dots <- rlang::enquos(...)
named_by <- "by" %in% names(dots)
if ( named_by && ( rlang::is_character(dots$by) || ( rlang::is_call(dots$by, "c") && evaled_is(quoted_dots$by, "character") ) ) ) {
TRUE
}
else if (!named_by && length(dots) > 0L && rlang::is_call(dots[[1L]], "c") && evaled_is(quoted_dots[[1L]], "character")) {
TRUE
}
else {
FALSE
}
}
#' @importFrom rlang enquos
#' @importFrom rlang eval_tidy
#' @importFrom rlang sym
#'
dplyr_by_to_dots <- function(...) {
quoted_dots <- rlang::enquos(...)
if ("by" %in% names(quoted_dots)) {
bys <- rlang::eval_tidy(quoted_dots$by)
} else {
bys <- rlang::eval_tidy(quoted_dots[[1L]])
}
lapply(bys, rlang::sym)
}
# TODO keep and suffix for dplyr joins?
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.