Вы можете sapply
на шаблонах и суммировать строки, чтобы найти то, что вам нужно.
Примечания:
- Я конвертирую ваши SQL -эскизовые шаблоны для регулярного выражения здесь.
- при использовании
dplyr
, вероятно, лучше использовать его if_else
, так как эта версия лучше защищает от выходов различных классов (а также от некоторых других проблем с базой ifelse
). - Поскольку
%like%
является просто инфиксным оператором для функции like
(по крайней мере, в data.table
), для ясности я использую последний вариант (версия с предварительным исправлением).
sapply(c(".*apple.*", ".*vocado.*"), like, vector = fruits)
# .*apple.* .*vocado.*
# [1,] TRUE FALSE
# [2,] TRUE FALSE
# [3,] FALSE FALSE
# [4,] FALSE TRUE
# [5,] FALSE FALSE
rowSums(sapply(c(".*apple.*", ".*vocado.*"), like, vector = fruits)) > 0
# [1] TRUE TRUE FALSE TRUE FALSE
Это то, что нам нужно, вектор logical
. Я сделаю вспомогательную функцию для этого.
mylike <- function(x, ptns) rowSums(sapply(ptns, like, vector = x)) > 0
mylike(fruits, c(".*apple.*", ".*vocado.*"))
# [1] TRUE TRUE FALSE TRUE FALSE
mydata %>%
mutate(
group = if_else(mylike(fruits, c(".*apple.*", ".*vocado.*")), "group 1",
if_else(mylike(fruits, c(".*anana.*",".*grape.*")), "group 2", "group 3"))
)
# fruits color group
# 1 apple red group 1
# 2 pineapple yellow group 1
# 3 grape purple group 2
# 4 avocado green group 1
# 5 banana yellow group 2
Однако, когда я вижу вложенный ifelse
/ if_else
, я предлагаю case_when
, так как он гораздо более читабелен, особенно когда число условий увеличивается.
mydata %>%
mutate(
group = case_when(
mylike(fruits, c(".*apple.*", ".*vocado.*")) ~ "group 1",
mylike(fruits, c(".*anana.*",".*grape.*")) ~ "group 2",
TRUE ~ "group 3"
)
)
# fruits color group
# 1 apple red group 1
# 2 pineapple yellow group 1
# 3 grape purple group 2
# 4 avocado green group 1
# 5 banana yellow group 2
Если у вас уже есть набор SQL шаблонов и вы не хотите переводить их все в регулярные выражения, вот быстрая вспомогательная функция, основанная на https://codereview.stackexchange.com/a/36864/42300:
# https://codereview.stackexchange.com/a/36864/42300
sql2regex <- function(ptn) {
paste0(
"^",
gsub("_", ".",
gsub("(?<!\\[)%(?!\\])", ".*", ptn, perl = TRUE)),
"$")
}
Он пытается быть умным, чтобы не конвертировать [%]
, что является одним из способов "избежать" процента и go для его литерала (ref: http://www.sqlserver.info/syntax/sql-server-like-with-percent-literal/). Однако, даже если [%
может показаться неполным, это неверно переведено в ^[.*$
, вместо этого оно остается ^[%$
, что приведет к ошибке. Опять же, это всего лишь вспомогательная функция быстрого взлома.
mydata %>%
mutate(
group = case_when(
mylike(fruits, sql2regex(c("%pple%","%vocado%"))) ~ "group 1",
mylike(fruits, sql2regex(c("%anana%","%grape%"))) ~ "group 2",
TRUE ~ "group 3"
)
)
# fruits color group
# 1 apple red group 1
# 2 pineapple yellow group 1
# 3 grape purple group 2
# 4 avocado green group 1
# 5 banana yellow group 2