Skip to content

Commit 15a5f5b

Browse files
Merge pull request #1114 from r-lib/f-rbind
Prefer vctrs functions over slower base R equivalents
2 parents e5ecef7 + e4435d6 commit 15a5f5b

27 files changed

+112
-122
lines changed

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,6 @@ importFrom(rlang,is_installed)
5252
importFrom(rlang,seq2)
5353
importFrom(rlang,set_names)
5454
importFrom(rlang,warn)
55+
importFrom(vctrs,vec_rbind)
56+
importFrom(vctrs,vec_slice)
57+
importFrom(vctrs,vec_split)

R/compat-dplyr.R

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,17 @@ lead <- function(x, n = 1L, default = NA) {
1313

1414
arrange <- function(.data, ...) {
1515
ord <- eval(substitute(order(...)), .data, parent.frame())
16-
.data[ord, , drop = FALSE]
16+
vec_slice(.data, ord)
1717
}
1818

1919
arrange_pos_id <- function(data) {
2020
pos_id <- data$pos_id
2121
if (is.unsorted(pos_id)) {
22-
data <- data[order(pos_id), , drop = FALSE]
22+
data <- vec_slice(data, order(pos_id))
2323
}
2424
data
2525
}
2626

27-
bind_rows <- function(x, y = NULL, ...) {
28-
if (is.null(x) && is.null(y)) {
29-
return(new_styler_df(list()))
30-
}
31-
if (is.null(x)) {
32-
if (inherits(y, "data.frame")) {
33-
return(y)
34-
}
35-
return(do.call(rbind.data.frame, x))
36-
}
37-
if (is.null(y)) {
38-
if (inherits(x, "data.frame")) {
39-
return(x)
40-
}
41-
return(do.call(rbind.data.frame, x))
42-
}
43-
if (NCOL(x) != NCOL(y)) {
44-
for (nme in setdiff(names(x), names(y))) {
45-
y[[nme]] <- NA
46-
}
47-
}
48-
bind_rows(rbind.data.frame(x, y), ...)
49-
}
50-
5127
filter <- function(.data, ...) {
5228
subset(.data, ...)
5329
}
@@ -76,13 +52,8 @@ last <- function(x) {
7652
x[[length(x)]]
7753
}
7854

79-
slice <- function(.data, ...) {
80-
.data[c(...), , drop = FALSE]
81-
}
82-
83-
# TODO: Use `purrr::map_dfr()` when it stops implicitly relying on `{dplyr}`
84-
map_dfr <- function(.x, .f, ..., .id = NULL) {
55+
map_dfr <- function(.x, .f, ...) {
8556
.f <- purrr::as_mapper(.f, ...)
8657
res <- map(.x, .f, ...)
87-
bind_rows(res, .id = .id)
58+
vec_rbind(!!!res)
8859
}

R/compat-tidyr.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ nest_ <- function(data, key_col, nest_cols = character()) {
33
key_data <- data[[key_column]]
44
key_levels <- unique(key_data)
55
key_factor <- factor(key_data, levels = key_levels)
6-
res <- list()
7-
res[[key_column]] <- key_levels
8-
res[[key_col]] <- split(data[, nest_cols], key_factor)
9-
new_styler_df(res)
6+
7+
res <- vec_split(data[, nest_cols], key_factor)
8+
names(res) <- c(key_column, key_col)
9+
res
1010
}

R/detect-alignment-utils.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ alignment_ensure_no_closing_brace <- function(pd_by_line,
1515
pd_by_line[-length(pd_by_line)]
1616
} else {
1717
# only drop last elment of last line
18-
pd_by_line[[length(pd_by_line)]] <- last[seq2(1L, nrow(last) - 1L), ]
18+
pd_by_line[[length(pd_by_line)]] <- vec_slice(last, seq2(1L, nrow(last) - 1L))
1919
pd_by_line
2020
}
2121
}
@@ -29,7 +29,7 @@ alignment_ensure_no_closing_brace <- function(pd_by_line,
2929
#' @keywords internal
3030
alignment_drop_comments <- function(pd_by_line) {
3131
map(pd_by_line, function(x) {
32-
out <- x[x$token != "COMMENT", ]
32+
out <- vec_slice(x, x$token != "COMMENT")
3333
if (nrow(out) < 1L) {
3434
return(NULL)
3535
} else {
@@ -62,7 +62,7 @@ alignment_drop_last_expr <- function(pds_by_line) {
6262
pd_last_line <- pds_by_line[[length(pds_by_line)]]
6363
last_two_lines <- pd_last_line$token[c(nrow(pd_last_line) - 1L, nrow(pd_last_line))]
6464
if (identical(last_two_lines, c("')'", "expr"))) {
65-
pd_last_line <- pd_last_line[-nrow(pd_last_line), ]
65+
pd_last_line <- vec_slice(pd_last_line, -nrow(pd_last_line))
6666
}
6767
pds_by_line[[length(pds_by_line)]] <- pd_last_line
6868
pds_by_line
@@ -141,7 +141,7 @@ alignment_serialize_line <- function(relevant_pd_by_line, column) {
141141
return(NULL)
142142
}
143143
between_commas <- seq2(max(1L, comma_idx[column - 1L]), comma_idx[column])
144-
relevant_pd_by_line <- relevant_pd_by_line[between_commas, ]
144+
relevant_pd_by_line <- vec_slice(relevant_pd_by_line, between_commas)
145145
alignment_serialize(relevant_pd_by_line)
146146
}
147147

R/detect-alignment.R

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ token_is_on_aligned_line <- function(pd_flat) {
4646
# pos_id too expensive to construct in alignment_ensure_trailing_comma()
4747
pd_flat$lag_newlines <- pd_flat$pos_id <- NULL
4848
pd_flat$.lag_spaces <- lag(pd_flat$spaces)
49-
pd_by_line <- split(pd_flat, line_idx)
49+
pd_by_line_split <- vec_split(pd_flat, line_idx)
50+
51+
# FIXME: Why are we using names here?
52+
pd_by_line <- pd_by_line_split[[2L]]
53+
names(pd_by_line) <- as.character(pd_by_line_split[[1L]])
54+
5055
pd_by_line[purrr::map_lgl(pd_by_line, ~ any(.x$stylerignore))] <- NULL
5156
if (length(pd_by_line) < 1L) {
5257
return(TRUE)

R/indent.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ needs_indention_one <- function(pd,
179179
potential_trigger_pos, before_first_break
180180
)
181181
multi_line_token <- pd_is_multi_line(
182-
pd[row_idx_between_trigger_and_line_break, ]
182+
vec_slice(pd, row_idx_between_trigger_and_line_break)
183183
)
184184
remaining_row_idx_between_trigger_and_line_break <- setdiff(
185185
row_idx_between_trigger_and_line_break,

R/nest.R

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ add_cache_block <- function(pd_nested) {
9999
shallowify <- function(pd) {
100100
if (cache_is_activated()) {
101101
order <- order(pd$line1, pd$col1, -pd$line2, -pd$col2, as.integer(pd$terminal))
102-
pd_parent_first <- pd[order, ]
103-
pos_ids_to_keep <- pd_parent_first %>%
104-
split(cumsum(pd_parent_first$parent == 0L)) %>%
102+
pd_parent_first <- vec_slice(pd, order)
103+
pd_parent_first_split <- vec_split(pd_parent_first, cumsum(pd_parent_first$parent == 0L))
104+
pos_ids_to_keep <- pd_parent_first_split[[2L]] %>%
105105
map(find_pos_id_to_keep) %>%
106106
unlist(use.names = FALSE)
107-
shallow <- pd[pd$pos_id %in% pos_ids_to_keep, ]
107+
shallow <- vec_slice(pd, pd$pos_id %in% pos_ids_to_keep)
108108
shallow$terminal[shallow$is_cached] <- TRUE
109109
# all cached expressions need to be marked as terminals because to
110110
# [apply_stylerignore()], we rely on terminals only.
@@ -335,10 +335,9 @@ nest_parse_data <- function(pd_flat) {
335335
return(pd_flat)
336336
}
337337
pd_flat$internal <- with(pd_flat, (id %in% parent) | (parent <= 0L))
338-
split_data <- split(pd_flat, pd_flat$internal)
339338

340-
child <- split_data$`FALSE`
341-
internal <- split_data$`TRUE`
339+
child <- vec_slice(pd_flat, !pd_flat$internal)
340+
internal <- vec_slice(pd_flat, pd_flat$internal)
342341

343342
internal$internal_child <- internal$child
344343
internal$child <- NULL
@@ -367,14 +366,14 @@ nest_parse_data <- function(pd_flat) {
367366
#' the correct order.
368367
#' @param child A parse table or `NULL`.
369368
#' @param internal_child A parse table or `NULL`.
370-
#' @details Essentially, this is a wrapper around [dplyr::bind_rows()], but
371-
#' returns `NULL` if the result of [dplyr::bind_rows()] is a data frame with
369+
#' @details Essentially, this is a wrapper around vctrs::vec_rbind()], but
370+
#' returns `NULL` if the result of vctrs::vec_rbind()] is a data frame with
372371
#' zero rows.
373372
#' @keywords internal
374373
combine_children <- function(child, internal_child) {
375-
bound <- bind_rows(child, internal_child)
374+
bound <- vec_rbind(child, internal_child)
376375
if (nrow(bound) == 0L) {
377376
return(NULL)
378377
}
379-
bound[order(bound$pos_id), ]
378+
vec_slice(bound, order(bound$pos_id))
380379
}

R/parse.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ ensure_correct_txt <- function(pd, text) {
137137
if (!any(is_problematic_text)) {
138138
return(pd)
139139
}
140-
problematic_text <- pd[is_problematic_text, ]
140+
problematic_text <- vec_slice(pd, is_problematic_text)
141141
is_parent_of_problematic_string <- pd$id %in% problematic_text$parent
142142

143143
is_unaffected_token <- !magrittr::or(
@@ -167,10 +167,10 @@ ensure_correct_txt <- function(pd, text) {
167167
names(new_text),
168168
paste0(line_col_names(), "parent")
169169
)
170-
bind_rows(
170+
vec_rbind(
171171
new_text[, names_to_keep],
172-
pd[is_unaffected_token, ],
173-
pd[is_parent_of_problematic_string, ]
172+
vec_slice(pd, is_unaffected_token),
173+
vec_slice(pd, is_parent_of_problematic_string)
174174
) %>%
175175
arrange_pos_id()
176176
}

R/reindent.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ set_regex_indention <- function(flattened_pd,
9696
if (length(cond) < 1L) {
9797
return(flattened_pd)
9898
}
99-
to_check <- flattened_pd[cond, ]
100-
not_to_check <- flattened_pd[-cond, ]
99+
to_check <- vec_slice(flattened_pd, cond)
100+
not_to_check <- vec_slice(flattened_pd, -cond)
101101
} else {
102102
to_check <- flattened_pd
103103
not_to_check <- NULL
@@ -108,6 +108,6 @@ set_regex_indention <- function(flattened_pd,
108108
flatten_int()
109109

110110
to_check$lag_spaces[indices_to_force] <- target_indention
111-
bind_rows(to_check, not_to_check) %>%
111+
vec_rbind(to_check, not_to_check) %>%
112112
arrange_pos_id()
113113
}

R/relevel.R

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ flatten_pd <- function(pd_nested, token, child_token = token, left = TRUE) {
8585
#' @keywords internal
8686
bind_with_child <- function(pd_nested, pos) {
8787
pd_nested %>%
88-
slice(-pos) %>%
89-
bind_rows(pd_nested$child[[pos]]) %>%
88+
vec_slice(-pos) %>%
89+
vec_rbind(pd_nested$child[[pos]]) %>%
9090
arrange_pos_id()
9191
}
9292

@@ -178,8 +178,8 @@ relocate_eq_assign_nest <- function(pd) {
178178
idx_eq_assign <- which(pd$token == "EQ_ASSIGN")
179179
if (length(idx_eq_assign) > 0L) {
180180
block_id <- find_block_id(pd)
181-
blocks <- split(pd, block_id)
182-
pd <- map_dfr(blocks, relocate_eq_assign_one)
181+
blocks <- vec_split(pd, block_id)
182+
pd <- map_dfr(blocks[[2L]], relocate_eq_assign_one)
183183
}
184184
pd
185185
}
@@ -217,7 +217,7 @@ relocate_eq_assign_one <- function(pd) {
217217
eq_ind <- seq2(idx_eq_assign[1L] - 1L, last(idx_eq_assign) + 1L)
218218
# initialize because wrap_expr_in_expr -> create_tokens -> requires it
219219
pd$indent <- 0L
220-
eq_expr <- pd[eq_ind, ] %>%
220+
eq_expr <- vec_slice(pd, eq_ind) %>%
221221
wrap_expr_in_expr() %>%
222222
add_line_col_to_wrapped_expr() %>%
223223
remove_attributes(c(
@@ -227,8 +227,8 @@ relocate_eq_assign_one <- function(pd) {
227227
eq_expr$id <- NA
228228
eq_expr$parent <- NA
229229
pd$indent <- NULL
230-
non_eq_expr <- pd[-eq_ind, ]
231-
pd <- bind_rows(eq_expr, non_eq_expr) %>%
230+
non_eq_expr <- vec_slice(pd, -eq_ind)
231+
pd <- vec_rbind(eq_expr, non_eq_expr) %>%
232232
arrange_pos_id()
233233
pd
234234
}

0 commit comments

Comments
 (0)