Sparklyr Spark SQL Filter на основе нескольких подстановочных знаков - PullRequest
1 голос
/ 22 июня 2019

Используя sparklyr, я пытаюсь найти способ фильтрации данных в Spark, объединяющих функциональность rlike и %in%.Вот минимальный рабочий пример:

# start a Spark session in R and have dplyr loaded

# create a spark dataframe
df <- data.frame(names = c("Brandon", "Chee", "Brandi", "Firouz", "Eric", "Erin"),
                 place = c("Pasadena", "South Bay", "West Hollywood", "SF Valley", "South Bay", "South Bay"))
sc_df <- sdf_copy_to(sc, df, overwrite = TRUE)

# set wildcard filter paramaters
f_params <- c("Brand", "Er")

# return all rows of sc_df where the 'names' value contains either 'f_params' values.
df_filtered <- sc_df %>% 
  filter(rlike(names, f_params)) %>% 
  collect()

df_filtered в приведенном выше коде явно не работает.В идеале таблица df_filtered должна выглядеть следующим образом:

print(df_filtered)
# names     place           
# Brandon   Pasadena      
# Brandi    West Hollywood
# Eric      South Bay     
# Erin      South Bay 

Дополнительное правило : поскольку реальный пример содержит около 200 значений в f_params, я не могу использовать следующее решение:

df_filtered <- sc_df %>% 
  filter(rlike(names, "Brand") | rlike(names, "Er")) %>% 
  collect()

Заранее спасибо.

1 Ответ

2 голосов
/ 22 июня 2019

Я не могу использовать несколько операторов rlike (), разделенных | (ИЛИ), потому что реальный пример включает в себя около 200 значений в f_params

Это звучит как довольно искусственное ограничение, но если вы действительно хотите избежать одного регулярного выражения, вы всегда можете составить явную дизъюнкцию:

library(rlang)

sc_df %>% 
  filter(!!rlang::parse_quo(glue::glue_collapse(glue::glue(
    "(names %rlike% '{f_params}')"), 
    " %or% "  # or " | "
  ), rlang::caller_env()))
# Source: spark<?> [?? x 2]
  names   place         
  <chr>   <chr>         
1 Brandon Pasadena      
2 Brandi  West Hollywood
3 Eric    South Bay     
4 Erin    South Bay 

Если f_params гарантированно является допустимым литералом регулярного выражения, то гораздо быстрее будет просто объединить строку:

sc_df %>% 
  filter(names %rlike% glue::glue_collapse(glue::glue("{f_params}"), "|"))
# Source: spark<?> [?? x 2]
  names   place         
  <chr>   <chr>         
1 Brandon Pasadena      
2 Brandi  West Hollywood
3 Eric    South Bay     
4 Erin    South Bay  

Если нет, попробуйте сначала применить Hmisc::escapeRegexp:

sc_df %>% 
  filter(
    names %rlike% glue::glue_collapse(glue::glue(
      "{Hmisc::escapeRegex(f_params)}"
    ), "|")
  )

но имейте в виду, что Spark использует регулярное выражение Java, поэтому оно может не охватывать некоторые крайние случаи.

...