Joshua Rosenberg
Joshua Rosenberg

Reputation: 4226

Create data.frame for each connection between identifier in vector and from list (of vectors) in R

I have network data that consists of two columns, the first, a sender identifier, a vector of length 1 and the second, a receiver identifier, which is a vector of length 1 or more. This is the tricky part, the idea is each sender can connect with one or more receiver.

I am trying to create a data.frame with two columns, one for sender and one for receiver, with each pairwise connection. Here is the goal for what the final data should look like:

output <- 
    data.frame(sender = c("person_1", c("person_2", "person_2"), "person_3", c("person_4", "person_4"), "person_5"),
               receiver = c("person_6", c("person_7", "person_8"), "person_9", c("person_10", "person_11"), "person_12"))

> output
    sender  receiver
1 person_1  person_6
2 person_2  person_7
3 person_2  person_8
4 person_3  person_9
5 person_4 person_10
6 person_4 person_11
7 person_5 person_12

Here is the data:

sender <- paste("person_", 1:5, sep = "")
receiver <- list("person_6", c("person_7", "person_8"), "person_9", c("person_10", "person_11"), "person_12")

> str(sender)
 chr [1:5] "person_1" "person_2" "person_3" "person_4" "person_5"

> str(receiver)
List of 5
 $ : chr "person_6"
 $ : chr [1:2] "person_7" "person_8"
 $ : chr "person_9"
 $ : chr [1:2] "person_10" "person_11"
 $ : chr "person_12"

Upvotes: 2

Views: 28

Answers (1)

Frank
Frank

Reputation: 66819

One way would be to add sender names to relevant entries in the receiver list and then use the oddly-named function stack:

res0 = stack(setNames(receiver, sender))[, 2:1]

The names in the result are weird, so you might want to change them

res = setNames(res0, c("sender", "receiver"))

    sender  receiver
1 person_1  person_6
2 person_2  person_7
3 person_2  person_8
4 person_3  person_9
5 person_4 person_10
6 person_4 person_11
7 person_5 person_12

This matches the OP's output object apart from column classes.


I would probably use magrittr for readability here instead of the code above:

library(magrittr)
receiver %>% setNames(sender) %>% stack %>% rev %>% setNames(c("sender", "receiver"))

Alternately (and I don't want to recommend this...):

library(tidyr)
library(tibble)
data_frame(sender, receiver) %>% unnest(receiver)

Upvotes: 2

Related Questions