Предположим, у меня есть эти данные:
data <- tibble(
x = c("ANOTHER", "COMMON", "ZEBRA")
)
И я хочу объединить этот фрейм данных с этим:
Обновлено: префикс не имеет фиксированной длины.
selection <- tibble(
x_prefix = c("A", "B", "CO"),
type = c("One type", "Other type", "Other type")
)
Я хочу сделать ВНУТРЕННЕЕ СОЕДИНЕНИЕ со столбцами x и x_prefix с идеей, что строка сохраняется, если x_prefix является префиксом x.
Ожидаемый ответ:
answer <- tibble(
x = c("ANOTHER", "COMMON"),
type = c("One type", "Other type")
)
Как это можно сделать с помощью dplyr?
@Фриде Нет!!!
Я подозреваю, что, поскольку вы ищете {tidyverse} решение, вы можете позаимствовать код здесь: stackoverflow.com/a/67377408/20002111 Не тестировал.





Вы можете использовать fuuzy_inner_join с str_detect в качестве функции сопоставления. Символ «^» взят из регулярного выражения и означает начало строки, поэтому нам нужно добавить его к вашему шаблону, чтобы сопоставлять только строки, начинающиеся с paste.
library(fuzzyjoin)
library(tidyverse)
fuzzy_inner_join(data, selection, by = c("x" = "x_prefix"),
match_fun = \(x, y) str_detect(x, paste0("^", y))) |>
select(-x_prefix)
# A tibble: 2 x 2
x type
<chr> <chr>
1 ANOTHER One type
2 COMMON Other type
Очевидным решением является создание временного столбца x_prefix и внутреннего соединения по нему.
data %>%
mutate(x_prefix = substr(x, 1, 1)) %>%
inner_join(selection, by = "x_prefix") %>%
select(-x_prefix)
#> # A tibble: 2 x 2
#> x type
#> <chr> <chr>
#> 1 ANOTHER One type
#> 2 COMMON Other type
Обновлю вопрос, но длина префикса не фиксирована
Решение на базе R (но может быть не таким эффективным с точки зрения памяти из-за outer)
> (d <- outer(data$x, selection$x_prefix, Vectorize(startsWith)))
[,1] [,2] [,3]
[1,] TRUE FALSE FALSE
[2,] FALSE FALSE TRUE
[3,] FALSE FALSE FALSE
> (idx <- rowSums(col(d) * d))
[1] 1 3 0
> cbind(data[idx > 0, ], selection[idx[idx > 0], "type"])
x type
1 ANOTHER One type
2 COMMON Other type
dataнетtypeколонки?