使用 tidygraph 生成的列表列重塑数据框
Reshaping a data frame with a list column produced by tidygraph
我正在使用 tidygraph
包并尝试找到 "tidy" 解决方案
对于下面的例子。这个问题并没有真正与 tidygraph
相关,更多的是关于数据争论,但我认为使用这个包的人很有趣。
在下面的代码块中,我只是生成了一些样本数据。
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()
结果 data.frame
如下所示:
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>
现在谈谈我的实际问题。我想对列 graph
中的每个元素应用一个函数。结果只是一个命名向量。
sub_graphs_df$graph %>% map(degree)
我不喜欢的第一件事是 $
的子集化。有没有更好的方法?
接下来,我想将此结果重塑为只有一个 data.frame 的 3 列。一列用于 name
(向量的名称属性),一列用于 group
(列表的名称属性),一列用于 number
(向量的元素)。
我尝试了 reshape2
包中的 melt
。
sub_graphs_df$graph %>% map(degree) %>% melt
它工作得很好,但名字丢失了,当我读到它时,应该使用
tidyr
代替。但是,我无法让 gather
工作,因为只接受 data.frames
。
另一种选择是 unlist
:
sub_graphs_df$graph %>% map(degree) %>% unlist
此处组和名称位于名称属性中,我必须使用正则表达式来恢复它们。
我很确定有一种我想不到的简单方法。
我们可以使用 mutate
创建一个 list
列,同时应用 map
的函数,提取 names
和整数以及 unnest
来创建'long' 格式化数据集
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
我正在使用 tidygraph
包并尝试找到 "tidy" 解决方案
对于下面的例子。这个问题并没有真正与 tidygraph
相关,更多的是关于数据争论,但我认为使用这个包的人很有趣。
在下面的代码块中,我只是生成了一些样本数据。
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()
结果 data.frame
如下所示:
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>
现在谈谈我的实际问题。我想对列 graph
中的每个元素应用一个函数。结果只是一个命名向量。
sub_graphs_df$graph %>% map(degree)
我不喜欢的第一件事是 $
的子集化。有没有更好的方法?
接下来,我想将此结果重塑为只有一个 data.frame 的 3 列。一列用于 name
(向量的名称属性),一列用于 group
(列表的名称属性),一列用于 number
(向量的元素)。
我尝试了 reshape2
包中的 melt
。
sub_graphs_df$graph %>% map(degree) %>% melt
它工作得很好,但名字丢失了,当我读到它时,应该使用
tidyr
代替。但是,我无法让 gather
工作,因为只接受 data.frames
。
另一种选择是 unlist
:
sub_graphs_df$graph %>% map(degree) %>% unlist
此处组和名称位于名称属性中,我必须使用正则表达式来恢复它们。
我很确定有一种我想不到的简单方法。
我们可以使用 mutate
创建一个 list
列,同时应用 map
的函数,提取 names
和整数以及 unnest
来创建'long' 格式化数据集
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