Sparklyr: используйте group_by, а затем объединяйте строки из строк в группу.

Я пытаюсь использовать функции group_by() и mutate() в sparklyr для объединения строк в группу.

Вот простой пример, который, я думаю, должен работать, но не работает:

library(sparkylr)
d <- data.frame(id=c("1", "1", "2", "2", "1", "2"), 
             x=c("200", "200", "200", "201", "201", "201"), 
             y=c("This", "That", "The", "Other", "End", "End"))
d_sdf <- copy_to(sc, d, "d")
d_sdf %>% group_by(id, x) %>% mutate( y = paste(y, collapse = " "))

Я бы хотел, чтобы он произвел:

Source: local data frame [6 x 3]
Groups: id, x [4]

# A tibble: 6 x 3
      id      x         y
  <fctr> <fctr>     <chr>
1      1    200 This That
2      1    200 This That
3      2    200       The
4      2    201 Other End
5      1    201       End
6      2    201 Other End

Я получаю следующую ошибку:

Error: org.apache.spark.sql.AnalysisException: missing ) at 'AS' near '' '' in selection target; line 1 pos 42

Обратите внимание, что использование того же кода в data.frame отлично работает:

d %>% group_by(id, x) %>% mutate( y = paste(y, collapse = " "))

person Maggie    schedule 06.06.2017    source источник


Ответы (1)


Spark sql не нравится, если вы используете агрегатные функции без агрегирования, поэтому причина, по которой это работает в dplyr с обычным dataframe, но не в SparkDataFrame- sparklyr, переводит ваши команды в оператор sql. Вы можете заметить, что это происходит неправильно, если вы посмотрите на второй бит в сообщении об ошибке:

== SQL ==
SELECT `id`, `x`, CONCAT_WS(' ', `y`, ' ' AS "collapse") AS `y`

paste переводится в CONCAT_WS. Однако concat будет склеивать столбцы вместе.

Лучшим эквивалентом были бы collect_list и collect_set, но они производят list выходов.

Но вы можете опираться на это:

Если вы не хотите, чтобы одна и та же строка реплицировалась в вашем результате, вы можете использовать summarise, collect_list и paste:

res <- d_sdf %>% 
      group_by(id, x) %>% 
      summarise( yconcat =paste(collect_list(y)))

результат:

Source:     lazy query [?? x 3]
Database:   spark connection master=local[8] app=sparklyr local=TRUE
Grouped by: id

     id     x         y
  <chr> <chr>     <chr>
1     1   201       End
2     2   201 Other End
3     1   200 This That
4     2   200       The

вы можете соединить это обратно с вашими исходными данными, если вы делаете реплицированные строки:

d_sdf %>% left_join(res)

результат:

Source:     lazy query [?? x 4]
Database:   spark connection master=local[8] app=sparklyr local=TRUE

     id     x     y   yconcat
  <chr> <chr> <chr>     <chr>
1     1   200  This This That
2     1   200  That This That
3     2   200   The       The
4     2   201 Other Other End
5     1   201   End       End
6     2   201   End Other End
person Janna Maas    schedule 07.06.2017
comment
Спасибо, очень полезный ответ - person Maggie; 09.06.2017