Gruppieren einer Viele-zu-Viele-Beziehung aus einer zweispaltigen Zuordnung

Ich habe eine SQL-Tabelle, die beispielsweise Autoren und Bücher abbildet. Ich möchte verknüpfte Autoren und Bücher (Bücher desselben Autors und Autoren, die gemeinsam ein Buch geschrieben haben) in Gruppen zusammenfassen und herausfinden, wie groß diese Gruppen werden. Wenn zum Beispiel J.K. Rowling hat mit Junot Diaz zusammen geschrieben, und Junot Diaz hat mit Zadie Smith zusammen ein Buch geschrieben, dann möchte ich, dass alle drei Autoren in derselben Gruppe sind.

Hier ist ein Spielzeugdatensatz (h ​​/ t Matthew Dowle) mit einigen der Beziehungen, über die ich spreche:

set.seed(1)
authors <- replicate(100,sample(1:3,1))
book_id <- rep(1:100,times=authors)
author_id <- c(lapply(authors,sample,x=1:100,replace=FALSE),recursive=TRUE)
aubk <- data.table(author_id = author_id,book_id = book_id)
aubk[order(book_id,author_id),]

Hier sieht man, dass die Autoren 27 und 36 Buch 2 mitschrieben, sie sollten also in derselben Gruppe sein. Gleiches gilt für die Autoren 63 und 100 für 3; und D, F und L für 4. Und so weiter.

Ich kann mir keinen anderen Weg vorstellen, dies zu tun, als eine for-Schleife, die (wie Sie sich vorstellen können) langsam ist. Ich habe ein bisschen ausprobiertdata.table um unnötiges Kopieren zu vermeiden. Gibt es eine bessere Möglichkeit?

aubk$group <- integer(dim(aubk)[1])
library(data.table)
aubk <- data.table(aubk)
#system.time({
for (x in 1:dim(aubk)[1]) {
    if(identical(x,1)) {
        value <- 1L
    } else {
        sb <- aubk[1:(x-1),]
        index <- match(aubk[x,author_id],sb[,author_id])
        if (identical(index,NA_integer_)) {
            index <- match(aubk[x,book_id],sb[,book_id])
            if (identical(index,NA_integer_)) {
                value <- x
            } else {
                value <- aubk[index,group]
            }
        } else {
            value <- aubk[index,group]
        }
    }
    aubk[x,group:=value]
}
#})

BEARBEITEN: Wie von @Josh O'Brien und @thelatemail erwähnt, kann mein Problem auch so formuliert werden, dass ich die verbundenen Komponenten eines Diagramms aus einer zweispaltigen Liste suche, in der jede Kante eine Zeile ist und die beiden Spalten die verbundenen Knoten sind.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage