| nest_join | R Documentation |
nest_join() keeps every row and column of x and adds one list column. Each element of that column is a
data.frame holding the rows of y whose keys match the row of x. A row of x without a match in y gets a
data.frame with zero rows.
nest_join(x, y, by = NULL, copy = FALSE, keep = FALSE, name = NULL, ...)
x, y |
The |
by |
A character vector naming the key columns. With Name the elements of
|
copy |
Ignored. Included for compatibility with |
keep |
|
name |
|
... |
Ignored. Included for compatibility with |
As rows of x are never dropped or repeated, the result always has as many rows as x. The other joins can be
built on top of it. Counting the rows of each nested data.frame tells you which rows semi_join() and
anti_join() would keep, and expanding the nested rows back out gives the result of inner_join() or, if the empty
matches become missing values, left_join().
A data.frame with the rows and columns of x and a list column, name, of data.frames. The join keys of x
are coerced to the common type of the keys in x and y. Groups are taken from x.
customers <- data.frame(id = 1:3, customer = c("Ana", "Ben", "Chloe"))
orders <- data.frame(id = c(1L, 1L, 3L, 4L), item = c("tea", "jam", "bread", "milk"))
# Ben (id 2) has no orders, so gets a zero row data.frame
res <- nest_join(customers, orders, by = "id")
res$orders
# Keep the key column in the nested data and choose the column name
nest_join(customers, orders, by = "id", keep = TRUE, name = "purchases")$purchases
# Counting the orders of each customer gives semi_join() and anti_join()
n_orders <- vapply(res$orders, nrow, integer(1L))
res[n_orders > 0L, c("id", "customer")] # semi_join(customers, orders, by = "id")
res[n_orders == 0L, c("id", "customer")] # anti_join(customers, orders, by = "id")
# Expanding the orders back out gives inner_join()
expand_matches <- function(x, nested) {
n <- vapply(nested, nrow, integer(1L))
cbind(x[rep(seq_len(nrow(x)), n), , drop = FALSE], do.call(rbind, nested), row.names = NULL)
}
expand_matches(res[c("id", "customer")], res$orders) # inner_join(customers, orders, by = "id")
# and left_join() once each empty match becomes a row of missing values
filled <- lapply(
res$orders,
function(o) if (nrow(o) == 0L) o[NA_integer_, , drop = FALSE] else o
)
expand_matches(res[c("id", "customer")], filled) # left_join(customers, orders, by = "id")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.