1

I am working with the tidygraph package and try to find a "tidy" solution for the example below. The problem is not really tied to tidygraph and more about data wrangling but I think it is interesting for people working with this package.

In the following code chunk I just generate some sample data.

library(tidyverse)
library(tidygraph)
library(igraph)
library(randomNames)
library(reshape2)

graph <- play_smallworld(1, 100, 3, 0.05) 

labeled_graph <- graph %>% 
                    activate(nodes) %>%
                    mutate(group = sample(letters[1:3], size = 100, replace = TRUE),
                           name = randomNames(100)
                           )

sub_graphs_df <- labeled_graph %>% 
                    morph(to_split, group) %>%
                    crystallise()

The resulting data.frame looks as follows:

sub_graphs_df
# A tibble: 3 x 2
      name           graph
     <chr>          <list>
1 group: a <S3: tbl_graph>
2 group: b <S3: tbl_graph>
3 group: c <S3: tbl_graph>

Now to my actual problem. I want do apply a function to each element in the column graph. The result is simply a named vector.

sub_graphs_df$graph %>% map(degree)

The first thing I do not like is the subsetting by $. Is there a better way?

Next, I want to reshape this result into only one data.frame with 3 columns. One column for name (the name attribute of the vectors), one for group (the name attribute of the list) and one for the number (the elements of the vectors).

I tried melt from the reshape2 package.

sub_graphs_df$graph %>% map(degree) %>% melt

It works decently but the names are lost and as I read it, one should use tidyr instead. However, I could not get gather to work because only data.frames are accepted.

Another option would be unlist:

sub_graphs_df$graph %>% map(degree) %>% unlist

Here the group and the name are in the names attribute and I would have to recover them with regular expressions.

I am pretty sure there is an easy way I just could not think of.

4

1 回答 1

2

We can create a list column with mutate while applying the function with map, extract the names and integer and unnest to create the 'long' format dataset

sub_graphs_df %>%
   mutate(newout = map(graph, degree)) %>%
   transmute(name, group = map(newout, ~.x %>% names), number = map(newout, as.integer)) %>%
    unnest
# A tibble: 100 x 3
#   name     group              number
#   <chr>    <chr>               <int>
# 1 group: a Seng, Trevor            0
# 2 group: a Buccieri, Joshua        1
# 3 group: a Street, Aimee           2
# 4 group: a Gonzalez, Corey         2
# 5 group: a Barber, Monique         1
# 6 group: a Doan, Christina         1
# 7 group: a Ninomiya, Janna         1
# 8 group: a Bazemore, Chao          1
# 9 group: a Perfecto, Jennifer      1
#10 group: a Lopez Jr, Vinette       0
# ... with 90 more rows
于 2018-01-11T12:25:33.287 回答