Skip to content

Commit 5141ef5

Browse files
authored
Use vctrs internally (#4868)
1 parent 7571122 commit 5141ef5

File tree

110 files changed

+728
-671
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+728
-671
lines changed

DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Imports:
4343
scales (>= 1.2.0),
4444
stats,
4545
tibble,
46+
vctrs (>= 0.4.1),
4647
withr (>= 2.0.0)
4748
Suggests:
4849
covr,
@@ -79,7 +80,7 @@ Config/testthat/edition: 3
7980
Encoding: UTF-8
8081
LazyData: true
8182
Roxygen: list(markdown = TRUE)
82-
RoxygenNote: 7.2.0
83+
RoxygenNote: 7.2.0.9000
8384
Collate:
8485
'ggproto.r'
8586
'ggplot-global.R'

NAMESPACE

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,20 @@ S3method("$",ggproto)
44
S3method("$",ggproto_parent)
55
S3method("$<-",uneval)
66
S3method("+",gg)
7-
S3method("[",mapped_discrete)
87
S3method("[",uneval)
9-
S3method("[<-",mapped_discrete)
108
S3method("[<-",uneval)
119
S3method("[[",ggproto)
1210
S3method("[[<-",uneval)
1311
S3method(.DollarNames,ggproto)
14-
S3method(as.data.frame,mapped_discrete)
1512
S3method(as.list,ggproto)
1613
S3method(autolayer,default)
1714
S3method(autoplot,default)
18-
S3method(c,mapped_discrete)
1915
S3method(drawDetails,zeroGrob)
2016
S3method(element_grob,element_blank)
2117
S3method(element_grob,element_line)
2218
S3method(element_grob,element_rect)
2319
S3method(element_grob,element_text)
20+
S3method(format,ggplot2_mapped_discrete)
2421
S3method(format,ggproto)
2522
S3method(format,ggproto_method)
2623
S3method(fortify,"NULL")
@@ -142,6 +139,30 @@ S3method(scale_type,sfc)
142139
S3method(single_value,default)
143140
S3method(single_value,factor)
144141
S3method(summary,ggplot)
142+
S3method(vec_arith,ggplot2_mapped_discrete)
143+
S3method(vec_arith.ggplot2_mapped_discrete,MISSING)
144+
S3method(vec_arith.ggplot2_mapped_discrete,default)
145+
S3method(vec_arith.ggplot2_mapped_discrete,ggplot2_mapped_discrete)
146+
S3method(vec_arith.ggplot2_mapped_discrete,numeric)
147+
S3method(vec_arith.numeric,ggplot2_mapped_discrete)
148+
S3method(vec_cast,character.ggplot2_mapped_discrete)
149+
S3method(vec_cast,double.ggplot2_mapped_discrete)
150+
S3method(vec_cast,factor.ggplot2_mapped_discrete)
151+
S3method(vec_cast,ggplot2_mapped_discrete.double)
152+
S3method(vec_cast,ggplot2_mapped_discrete.factor)
153+
S3method(vec_cast,ggplot2_mapped_discrete.ggplot2_mapped_discrete)
154+
S3method(vec_cast,ggplot2_mapped_discrete.integer)
155+
S3method(vec_cast,integer.ggplot2_mapped_discrete)
156+
S3method(vec_math,ggplot2_mapped_discrete)
157+
S3method(vec_ptype2,character.ggplot2_mapped_discrete)
158+
S3method(vec_ptype2,double.ggplot2_mapped_discrete)
159+
S3method(vec_ptype2,factor.ggplot2_mapped_discrete)
160+
S3method(vec_ptype2,ggplot2_mapped_discrete.character)
161+
S3method(vec_ptype2,ggplot2_mapped_discrete.double)
162+
S3method(vec_ptype2,ggplot2_mapped_discrete.factor)
163+
S3method(vec_ptype2,ggplot2_mapped_discrete.ggplot2_mapped_discrete)
164+
S3method(vec_ptype2,ggplot2_mapped_discrete.integer)
165+
S3method(vec_ptype2,integer.ggplot2_mapped_discrete)
145166
S3method(widthDetails,titleGrob)
146167
S3method(widthDetails,zeroGrob)
147168
export("%+%")
@@ -668,6 +689,7 @@ export(update_geom_defaults)
668689
export(update_labels)
669690
export(update_stat_defaults)
670691
export(vars)
692+
export(vec_arith.ggplot2_mapped_discrete)
671693
export(waiver)
672694
export(wrap_dims)
673695
export(xlab)
@@ -679,6 +701,7 @@ import(grid)
679701
import(gtable)
680702
import(rlang)
681703
import(scales)
704+
import(vctrs)
682705
importFrom(glue,glue)
683706
importFrom(glue,glue_collapse)
684707
importFrom(lifecycle,deprecated)

R/aes.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ rename_aes <- function(x) {
179179
names(x) <- standardise_aes_names(names(x))
180180
duplicated_names <- names(x)[duplicated(names(x))]
181181
if (length(duplicated_names) > 0L) {
182-
cli::cli_warn("Duplicated aesthetics after name standardisation: {.field {unique(duplicated_names)}}")
182+
cli::cli_warn("Duplicated aesthetics after name standardisation: {.field {unique0(duplicated_names)}}")
183183
}
184184
x
185185
}

R/annotation-custom.r

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ GeomCustomAnn <- ggproto("GeomCustomAnn", Geom,
7373
if (!inherits(coord, "CoordCartesian")) {
7474
cli::cli_abort("{.fn annotation_custom} only works with {.fn coord_cartesian}")
7575
}
76-
corners <- new_data_frame(list(x = c(xmin, xmax), y = c(ymin, ymax)), n = 2)
76+
corners <- data_frame0(
77+
x = c(xmin, xmax),
78+
y = c(ymin, ymax),
79+
.size = 2
80+
)
7781
data <- coord$transform(corners, panel_params)
7882

7983
x_rng <- range(data$x, na.rm = TRUE)

R/annotation-logticks.r

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ GeomLogticks <- ggproto("GeomLogticks", Geom,
213213
}
214214
}
215215

216-
gTree(children = do.call("gList", ticks))
216+
gTree(children = inject(gList(!!!ticks)))
217217
},
218218

219219
default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = 1)
@@ -254,7 +254,12 @@ calc_logticks <- function(base = 10, ticks_per_base = base - 1,
254254
longtick_after_base <- floor(ticks_per_base/2)
255255
tickend[ cycleIdx == longtick_after_base ] <- midend
256256

257-
tickdf <- new_data_frame(list(value = ticks, start = start, end = tickend), n = length(ticks))
257+
tickdf <- data_frame0(
258+
value = ticks,
259+
start = start,
260+
end = tickend,
261+
.size = length(ticks)
262+
)
258263

259264
return(tickdf)
260265
}

R/annotation-map.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ GeomAnnotationMap <- ggproto("GeomAnnotationMap", GeomMap,
9393
# must be sequential integers
9494
coords <- coord_munch(coord, map, panel_params)
9595
coords$group <- coords$group %||% coords$id
96-
grob_id <- match(coords$group, unique(coords$group))
96+
grob_id <- match(coords$group, unique0(coords$group))
9797

9898
polygonGrob(coords$x, coords$y, default.units = "native",
9999
id = grob_id,

R/annotation-raster.r

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ GeomRasterAnn <- ggproto("GeomRasterAnn", Geom,
7676
if (!inherits(coord, "CoordCartesian")) {
7777
cli::cli_abort("{.fn annotation_raster} only works with {.fn coord_cartesian}")
7878
}
79-
corners <- new_data_frame(list(x = c(xmin, xmax), y = c(ymin, ymax)), n = 2)
79+
corners <- data_frame0(
80+
x = c(xmin, xmax),
81+
y = c(ymin, ymax),
82+
.size = 2
83+
)
8084
data <- coord$transform(corners, panel_params)
8185

8286
x_rng <- range(data$x, na.rm = TRUE)

R/annotation.r

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ annotate <- function(geom, x = NULL, y = NULL, xmin = NULL, xmax = NULL,
5757

5858
# Check that all aesthetic have compatible lengths
5959
lengths <- vapply(aesthetics, length, integer(1))
60-
n <- unique(lengths)
60+
n <- unique0(lengths)
6161

6262
# if there is more than one unique length, ignore constants
6363
if (length(n) > 1L) {
@@ -71,7 +71,7 @@ annotate <- function(geom, x = NULL, y = NULL, xmin = NULL, xmax = NULL,
7171
cli::cli_abort("Unequal parameter lengths: {details}")
7272
}
7373

74-
data <- new_data_frame(position, n = n)
74+
data <- data_frame0(!!!position, .size = n)
7575
layer(
7676
geom = geom,
7777
params = list(

R/axis-secondary.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ AxisSecondary <- ggproto("AxisSecondary", NULL,
193193
full_range <- self$transform_range(old_range)
194194

195195
# Test for monotonicity
196-
if (length(unique(sign(diff(full_range)))) != 1)
196+
if (length(unique0(sign(diff(full_range)))) != 1)
197197
cli::cli_abort("Transformation for secondary axes must be monotonic")
198198
},
199199

R/bench.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ benchplot <- function(x) {
2626
times <- rbind(construct, build, render, draw)[, 1:3]
2727
times <- rbind(times, colSums(times))
2828

29-
cbind(
29+
vec_cbind(
3030
step = c("construct", "build", "render", "draw", "TOTAL"),
3131
mat_2_df(times)
3232
)

R/bin.R

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,15 @@ bin_out <- function(count = integer(0), x = numeric(0), width = numeric(0),
183183
xmin = x - width / 2, xmax = x + width / 2) {
184184
density <- count / width / sum(abs(count))
185185

186-
new_data_frame(list(
186+
data_frame0(
187187
count = count,
188188
x = x,
189189
xmin = xmin,
190190
xmax = xmax,
191191
width = width,
192192
density = density,
193193
ncount = count / max(abs(count)),
194-
ndensity = density / max(abs(density))
195-
), n = length(count))
194+
ndensity = density / max(abs(density)),
195+
.size = length(count)
196+
)
196197
}

R/compat-plyr.R

Lines changed: 14 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ id_var <- function(x, drop = FALSE) {
6262
id <- as.integer(x)
6363
n <- length(levels(x))
6464
} else {
65-
levels <- sort(unique(x), na.last = TRUE)
65+
levels <- sort(unique0(x), na.last = TRUE)
6666
id <- match(x, levels)
6767
n <- max(id)
6868
}
@@ -107,12 +107,12 @@ id <- function(.variables, drop = FALSE) {
107107
ndistinct <- vapply(ids, attr, "n", FUN.VALUE = numeric(1), USE.NAMES = FALSE)
108108
n <- prod(ndistinct)
109109
if (n > 2^31) {
110-
char_id <- do.call("paste", c(ids, sep = "\r"))
111-
res <- match(char_id, unique(char_id))
110+
char_id <- inject(paste(!!!ids, sep = "\r"))
111+
res <- match(char_id, unique0(char_id))
112112
}
113113
else {
114114
combs <- c(1, cumprod(ndistinct[-p]))
115-
mat <- do.call("cbind", ids)
115+
mat <- inject(cbind(!!!ids))
116116
res <- c((mat - 1L) %*% combs + 1L)
117117
}
118118
if (drop) {
@@ -153,13 +153,13 @@ count <- function(df, vars = NULL, wt_var = NULL) {
153153
wt <- .subset2(df, wt_var)
154154
freq <- vapply(split(wt, id), sum, numeric(1))
155155
}
156-
new_data_frame(c(as.list(labels), list(n = freq)))
156+
data_frame0(labels, n = freq)
157157
}
158158
# Adapted from plyr::join.keys
159159
# Create a shared unique id across two data frames such that common variable
160160
# combinations in the two data frames gets the same id
161161
join_keys <- function(x, y, by) {
162-
joint <- rbind_dfs(list(x[by], y[by]))
162+
joint <- vec_rbind(x[by], y[by])
163163
keys <- id(joint, drop = TRUE)
164164
n_x <- nrow(x)
165165
n_y <- nrow(y)
@@ -251,103 +251,6 @@ round_any <- function(x, accuracy, f = round) {
251251
}
252252
f(x/accuracy) * accuracy
253253
}
254-
#' Bind data frames together by common column names
255-
#'
256-
#' This function is akin to `plyr::rbind.fill`, `dplyr::bind_rows`, and
257-
#' `data.table::rbindlist`. It takes data frames in a list and stacks them on
258-
#' top of each other, filling out values with `NA` if the column is missing from
259-
#' a data.frame
260-
#'
261-
#' @param dfs A list of data frames
262-
#'
263-
#' @return A data.frame with the union of all columns from the data frames given
264-
#' in `dfs`
265-
#'
266-
#' @keywords internal
267-
#' @noRd
268-
#'
269-
rbind_dfs <- function(dfs) {
270-
out <- list()
271-
columns <- unique(unlist(lapply(dfs, names)))
272-
nrows <- vapply(dfs, .row_names_info, integer(1), type = 2L)
273-
total <- sum(nrows)
274-
if (length(columns) == 0) return(new_data_frame(list(), total))
275-
allocated <- rep(FALSE, length(columns))
276-
names(allocated) <- columns
277-
col_levels <- list()
278-
ord_levels <- list()
279-
for (df in dfs) {
280-
new_columns <- intersect(names(df), columns[!allocated])
281-
for (col in new_columns) {
282-
if (is.factor(df[[col]])) {
283-
all_ordered <- all(vapply(dfs, function(df) {
284-
val <- .subset2(df, col)
285-
is.null(val) || is.ordered(val)
286-
}, logical(1)))
287-
all_factors <- all(vapply(dfs, function(df) {
288-
val <- .subset2(df, col)
289-
is.null(val) || is.factor(val)
290-
}, logical(1)))
291-
if (all_ordered) {
292-
ord_levels[[col]] <- unique(unlist(lapply(dfs, function(df) levels(.subset2(df, col)))))
293-
} else if (all_factors) {
294-
col_levels[[col]] <- unique(unlist(lapply(dfs, function(df) levels(.subset2(df, col)))))
295-
}
296-
out[[col]] <- rep(NA_character_, total)
297-
} else {
298-
out[[col]] <- rep(.subset2(df, col)[1][NA], total)
299-
}
300-
}
301-
allocated[new_columns] <- TRUE
302-
if (all(allocated)) break
303-
}
304-
is_date <- lapply(out, inherits, 'Date')
305-
is_time <- lapply(out, inherits, 'POSIXct')
306-
pos <- c(cumsum(nrows) - nrows + 1)
307-
for (i in seq_along(dfs)) {
308-
df <- dfs[[i]]
309-
rng <- seq(pos[i], length.out = nrows[i])
310-
for (col in names(df)) {
311-
date_col <- inherits(df[[col]], 'Date')
312-
time_col <- inherits(df[[col]], 'POSIXct')
313-
if (is_date[[col]] && !date_col) {
314-
out[[col]][rng] <- as.Date(
315-
unclass(df[[col]]),
316-
origin = ggplot_global$date_origin
317-
)
318-
} else if (is_time[[col]] && !time_col) {
319-
out[[col]][rng] <- as.POSIXct(
320-
unclass(df[[col]]),
321-
origin = ggplot_global$time_origin
322-
)
323-
} else if (date_col || time_col || inherits(df[[col]], 'factor')) {
324-
out[[col]][rng] <- as.character(df[[col]])
325-
} else {
326-
out[[col]][rng] <- df[[col]]
327-
}
328-
}
329-
}
330-
for (col in names(ord_levels)) {
331-
out[[col]] <- ordered(out[[col]], levels = ord_levels[[col]])
332-
}
333-
for (col in names(col_levels)) {
334-
out[[col]] <- factor(out[[col]], levels = col_levels[[col]])
335-
}
336-
attributes(out) <- list(
337-
class = "data.frame",
338-
names = names(out),
339-
row.names = .set_row_names(total)
340-
)
341-
out
342-
}
343-
344-
# Info needed for rbind_dfs date/time handling
345-
on_load({
346-
date <- Sys.Date()
347-
ggplot_global$date_origin <- date - unclass(date)
348-
time <- Sys.time()
349-
ggplot_global$time_origin <- time - unclass(time)
350-
})
351254

352255
#' Apply function to unique subsets of a data.frame
353256
#'
@@ -370,17 +273,18 @@ on_load({
370273
#' @noRd
371274
dapply <- function(df, by, fun, ..., drop = TRUE) {
372275
grouping_cols <- .subset(df, by)
373-
fallback_order <- unique(c(by, names(df)))
276+
fallback_order <- unique0(c(by, names(df)))
374277
apply_fun <- function(x) {
375278
res <- fun(x, ...)
376279
if (is.null(res)) return(res)
377-
if (length(res) == 0) return(new_data_frame())
280+
if (length(res) == 0) return(data_frame0())
378281
vars <- lapply(setNames(by, by), function(col) .subset2(x, col)[1])
379282
if (is.matrix(res)) res <- split_matrix(res)
380283
if (is.null(names(res))) names(res) <- paste0("V", seq_along(res))
381-
if (all(by %in% names(res))) return(new_data_frame(unclass(res)))
284+
if (all(by %in% names(res))) return(data_frame0(!!!unclass(res)))
382285
res <- modify_list(unclass(vars), unclass(res))
383-
new_data_frame(res[intersect(c(fallback_order, names(res)), names(res))])
286+
res <- res[intersect(c(fallback_order, names(res)), names(res))]
287+
data_frame0(!!!res)
384288
}
385289

386290
# Shortcut when only one group
@@ -390,10 +294,11 @@ dapply <- function(df, by, fun, ..., drop = TRUE) {
390294

391295
ids <- id(grouping_cols, drop = drop)
392296
group_rows <- split_with_index(seq_len(nrow(df)), ids)
393-
rbind_dfs(lapply(seq_along(group_rows), function(i) {
297+
result <- lapply(seq_along(group_rows), function(i) {
394298
cur_data <- df_rows(df, group_rows[[i]])
395299
apply_fun(cur_data)
396-
}))
300+
})
301+
vec_rbind(!!!result)
397302
}
398303

399304
single_value <- function(x, ...) {

0 commit comments

Comments
 (0)