R: Create aggregation structure from parent/child relationship

Viewed 204

I want to create a aggregation structure in a database by using a parent-child relationship like the one in this dataframe:

df <- data.frame(Child=c("C","C11","C111","C112","C12","C121","C122","C123","C13","C131","C132"),
                 Parent=c("","C","C11","C11","C","C12","C12","C12","C","C13","C13"))

From this parent-child dataframe, I would like to get lists like this (for further use in a function):

list.C <- c("C11","C12","C13")
list.C11 <- c("C111","C112")
list.C12 <- c("C121","C122","C123")
list.C13 <- c("C131","C132")

I've been trying to create my list with a loop through the lines and an assign function, but didn't work... any idea how to create this -- or list vectors?

Thank you!

2 Answers

You don't need a for loop. I can propose you a data.table solution.

library(data.table)
setDT(df)

If you want your output to be a dataframe:

 df[,.(Child = list(Child)), by = Parent]
   Parent          Child
1:                     C
2:      C    C11,C12,C13
3:    C11      C111,C112
4:    C12 C121,C122,C123
5:    C13      C131,C132

If you prefer a list:

list_parents <- split(
  df[,.(list(Child)), by = Parent],
  by = "Parent"
)
list_parents
[[1]]
   Parent Child
1:            C

$C
   Parent       Child
1:      C C11,C12,C13

$C11
   Parent     Child
1:    C11 C111,C112

$C12
   Parent          Child
1:    C12 C121,C122,C123

$C13
   Parent     Child
1:    C13 C131,C132

We can use split in base R

split(as.character(df$Child), df$Parent)

If we want to remove the blanks in 'Parent'

lst1 <- with(subset(df, Parent != ''), split(as.character(Child),
             droplevels(Parent)))
Related