Спред в SparklyR / пивот в Spark - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь преобразовать мой код R (показанный ниже) в код Sparklyr R для работы с набором данных искры, чтобы получить конечный результат, как показано в таблице 1:

Использование справки из сообщения о переполнении стека Соберите в sparklyr и SparklyR, разделив один столбец Spark Data Frame на два столбца Мне удалось пройти весь путь, кроме последнего шага, касающегося Spread.

Нужна помощь:

  1. Реализация распространения через SparklyR
  2. Оптимизировать код любым способом

Таблица 1: Необходим конечный результат:

  var              n nmiss
1 Sepal.Length   150     0
2 Sepal.Width    150     0

R код для его достижения:

library(dplyr)
library(tidyr)
library(tibble)

data <- iris
data_tbl <- as_tibble(data)

profile <- data_tbl %>%
  select(Sepal.Length,Sepal.Width) %>%
  summarize_all(funs(
    n = n(), #Count
    nmiss=sum(as.numeric(is.na(.))) # MissingCount
   )) %>%
  gather(variable, value) %>%
  separate(variable, c("var", "stat"), sep = "_(?=[^_]*$)") %>% 
  spread(stat, value) 

Код искры:

sdf_gather <- function(tbl){
  all_cols <- colnames(tbl)
  lapply(all_cols, function(col_nm){
    tbl %>% 
      select(col_nm) %>% 
      mutate(key = col_nm) %>%
      rename(value = col_nm)  
  }) %>% 
    sdf_bind_rows() %>% 
    select(c('key', 'value'))
}


profile <- data_tbl %>%
  select(Sepal.Length,Sepal.Width ) %>%
  summarize_all(funs(
    n = n(), 
    nmiss=sum(as.numeric(is.na(.))) 
  )) %>%
  sdf_gather(.) %>%
  ft_regex_tokenizer(input_col="key", output_col="KeySplit", pattern="_(?=[^_]*$)") %>% 
  sdf_separate_column("KeySplit", into=c("var", "stat")) %>%
  select(var,stat,value) %>%
  sdf_register('profile')

1 Ответ

0 голосов
/ 24 января 2019

В этом конкретном случае (в общем случае, когда все столбцы имеют одинаковый тип, хотя, если вас интересует только пропущенная статистика данных, это может быть дополнительно ослаблено), вы можете использовать гораздо более простую структуру, чем эта.

С данными, определенными так:

df <- copy_to(sc, iris, overwrite = TRUE) 

gather столбцы (ниже я предполагаю функцию, как определено в мой ответ до Соберите в sparklyr )

long <- df %>% 
  select(Sepal_Length, Sepal_Width) %>% 
  sdf_gather("key", "value", "Sepal_Length", "Sepal_Width")

, а затем группировать и агрегировать:

long %>% 
  group_by(key) %>% 
  summarise(n = n(), nmiss = sum(as.numeric(is.na(value)), na.rm=TRUE))

с результатом как:

# Source: spark<?> [?? x 3]
  key              n nmiss
  <chr>        <dbl> <dbl>
1 Sepal_Length   150     0
2 Sepal_Width    150     0

Учитывая уменьшенный размер вывода, также хорошо собирать результат после агрегирования

agg <- df %>%
  select(Sepal_Length,Sepal_Width) %>%
    summarize_all(funs(
      n = n(),
      nmiss=sum(as.numeric(is.na(.))) # MissingCount
   )) %>% collect()

и примените вашу gather - spread логику к результату:

agg %>% 
  tidyr::gather(variable, value) %>%
  tidyr::separate(variable, c("var", "stat"), sep = "_(?=[^_]*$)") %>% 
  tidyr::spread(stat, value) 
# A tibble: 2 x 3
  var              n nmiss
  <chr>        <dbl> <dbl>
1 Sepal_Length   150     0
2 Sepal_Width    150     0

На самом деле последний подход должен быть превосходным с точки зрения производительности в данном конкретном случае.

...