Как объединить строки на основе группы как можно быстрее - PullRequest
3 голосов
/ 27 апреля 2020

У меня есть следующий фрейм данных

ClientVisitGUID LineNum TextCol
1                 1      This was a great
1                 2      report I did
2                 3      was performed today
2                 1      Another great report
2                 2      for this person
3                 2      good stuff
3                 1      I really write very
3                 3      when I put my
3                 4      mind to it

Я хотел бы объединить строки на основе ClientVisitGUID и номера строки, чтобы я мог получить следующий вывод

ClientVisitGUID TextCol
1               This was a great report I did
2               Another great report for this person was performed today
3               I really write very good stuff when I put my mind to it

Я пытался dplyr, но это занимает много времени и не может справиться с тысячами строк, что у меня есть

  resultset2<-resultset %>%
    group_by(ClientVisitGUID) %>%
    arrange(LineNum) %>%
    summarize_all(paste, collapse=",")

Есть ли более быстрый путь? Я не очень знаком с data.table, но так ли это быстро?

Ответы [ 3 ]

3 голосов
/ 27 апреля 2020

Базовая опция R использует aggregate

result <- aggregate(TextCol~ClientVisitGUID,
                    df[order(df$ClientVisitGUID,df$LineNum),],
                    paste0, 
                    collapse = " ")

, что дает

> result
  ClientVisitGUID                                                  TextCol
1               1                            This was a great report I did
2               2 Another great report for this person was performed today
3               3  I really write very good stuff when I put my mind to it

Данные

df <- structure(list(ClientVisitGUID = c(1L, 1L, 2L, 2L, 2L, 3L, 3L, 
3L, 3L), LineNum = c(1L, 2L, 3L, 1L, 2L, 2L, 1L, 3L, 4L), TextCol = c("This was a great", 
"report I did", "was performed today", "Another great report", 
"for this person", "good stuff", "I really write very", "when I put my", 
"mind to it")), class = "data.frame", row.names = c(NA, -9L))
3 голосов
/ 27 апреля 2020

Вторая опция data.table, также использующая stringi для своей производительности

library(data.table)
library(stringi)
setDT(df)
setkey(df, ClientVisitGUID, LineNum)
df1 <- df[, .(new = stri_c(TextCol, collapse = " ")), by = ClientVisitGUID]

Результат

df1
#   ClientVisitGUID                                                      new
#1:               1                            This was a great report I did
#2:               2 Another great report for this person was performed today
#3:               3  I really write very good stuff when I put my mind to it

data (благодаря @ThomasIsCoding)

df <- structure(list(ClientVisitGUID = c(1L, 1L, 2L, 2L, 2L, 3L, 3L, 
3L, 3L), LineNum = c(1L, 2L, 3L, 1L, 2L, 2L, 1L, 3L, 4L), TextCol = c("This was a great", 
"report I did", "was performed today", "Another great report", 
"for this person", "good stuff", "I really write very", "when I put my", 
"mind to it")), class = "data.frame", row.names = c(NA, -9L))
0 голосов
/ 27 апреля 2020

Если вам нужна скорость, data.table действительно хороший кандидат:

library(data.table)

setDT(resultset)
data.table::setkeyv(resultset, "ClientVisitGUID")
resultset <- resultset[order(ClientVisitGUID, LineNum)]
resultset[, .(lapply(.SD, paste, collapse = ",")), by = "ClientVisitGUID"]

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

Пример

data = data.table("a" = c("aaa","ffff","ttt"), "b" = c(1,1,2))
data[, .(lapply(.SD, paste, collapse = ",")), by = "b"]
...