如何根据 R 列表中的列重新排序 tidygraph 对象列表?
How to reorder a list of tidygraph objects based on a column in the list in R?
我有一个 tidygraph
对象的列表。我正在尝试根据特定条件对列表元素重新排序。也就是说,我的列表中的每个元素都有一个名为 name
的列。我正在尝试将具有相同 name
列的列表元素组合在一起......但我也想按照它们的计数降序对它们进行分组(即,等于 name
列的计数在每个列表元素中)。希望我的例子能解释得更清楚。
首先,我创建一些数据,将它们变成 tidygraph 对象并将它们放在一个列表中:
library(tidygraph)
library(tidyr)
# create some node and edge data for the tbl_graph
nodes1 <- data.frame(
name = c("x4", NA, NA),
val = c(1, 5, 2)
)
nodes2 <- data.frame(
name = c("x4", "x2", NA, NA, "x1", NA, NA),
val = c(3, 2, 2, 1, 1, 2, 7)
)
nodes3 <- data.frame(
name = c("x1", "x2", NA),
val = c(7, 4, 2)
)
nodes4 <- nodes1
nodes5 <- nodes2
nodes6 <- nodes1
edges <- data.frame(from = c(1, 1), to = c(2, 3))
edges1 <- data.frame(
from = c(1, 2, 2, 1, 5, 5),
to = c(2, 3, 4, 5, 6, 7)
)
# create the tbl_graphs
tg_1 <- tbl_graph(nodes = nodes1, edges = edges)
tg_2 <- tbl_graph(nodes = nodes2, edges = edges1)
tg_3 <- tbl_graph(nodes = nodes3, edges = edges)
tg_4 <- tbl_graph(nodes = nodes4, edges = edges)
tg_5 <- tbl_graph(nodes = nodes5, edges = edges1)
tg_6 <- tbl_graph(nodes = nodes6, edges = edges)
# put into list
myList <- list(tg_1, tg_2, tg_3, tg_4, tg_5, tg_6)
因此,我们可以看到 myList
中有 6 个 tidygraph
个对象。
检查每个元素,我们可以看到 3 个对象具有相同的 name
列(即 x4,NA,NA
).... 2 个对象具有相同的 name
列("x4", "x2", NA, NA, "x1", NA, NA
).. 剩下 1 个对象 (x1,x2,NA
).
使用一个小函数来获取同名列的计数:
# get a count of identical list elements based on `name` col
counts <- lapply(myList, function(x) {
x %>%
pull(name) %>%
paste0(collapse = "")
}) %>%
unlist(use.names = F) %>%
as_tibble() %>%
group_by(value) %>%
mutate(val = n():1) %>%
slice(1) %>%
arrange(-val)
为了清楚起见:
> counts
# A tibble: 3 × 2
# Groups: value [3]
value val
<chr> <int>
1 x4 NA NA 3
2 x4 x2 NA NA x1 NA NA 2
3 x1 x2 NA 1
我想根据 counts
对象中的 val
列重新排列 myList
中列表元素的顺序。
我想要的输出看起来像这样(我只是手动重新排序):
myList <- list(tg_1, tg_4, tg_6, tg_2, tg_5, tg_3)
有没有一种方法可以根据相同 name
列的数量自动重新排序我的列表?
更新:
所以我尝试的解决方案是执行以下操作:
ind <- map(myList, function(x){
x %>%
pull(name) %>%
replace_na("..") %>%
paste0(collapse = "")
}) %>%
unlist(use.names = F) %>%
as_tibble() %>%
mutate(ids = 1:n()) %>%
group_by(value) %>%
mutate(val = n():1) %>%
arrange(value) %>%
pull(ids)
# return new list of trees
myListNew <- myList[ind]
以上代码按 name
列和 returns 名为 ind
的索引对列表元素进行分组。然后我通过 ind
索引索引我的原始列表以重新排列我的列表。
但是,我仍然想找到一种方法来根据每个相同 name
变量的总量对新列表进行排序...我还没有弄清楚。
经过几个小时的测试,我终于有了一个可行的解决方案。
ind <- map(myList, function(x){
x %>%
pull(name) %>%
replace_na("..") %>%
paste0(collapse = "")
}) %>%
unlist(use.names = F) %>%
as_tibble() %>%
mutate(ids = 1:n()) %>%
group_by(value) %>%
mutate(val = n():1) %>%
arrange(value)
ind <- ind %>%
group_by(value) %>%
mutate(valrank = min(ids)) %>%
ungroup() %>%
arrange(valrank, value, desc(val)) %>%
pull(ids)
# return new list of trees
myListNew <- myList[ind]
以上代码按 name
字母顺序排列列表。然后我按名称分组并创建另一列对该行进行排名。然后我可以根据这个变量重新排列行。最后我按结果索引。
我有一个 tidygraph
对象的列表。我正在尝试根据特定条件对列表元素重新排序。也就是说,我的列表中的每个元素都有一个名为 name
的列。我正在尝试将具有相同 name
列的列表元素组合在一起......但我也想按照它们的计数降序对它们进行分组(即,等于 name
列的计数在每个列表元素中)。希望我的例子能解释得更清楚。
首先,我创建一些数据,将它们变成 tidygraph 对象并将它们放在一个列表中:
library(tidygraph)
library(tidyr)
# create some node and edge data for the tbl_graph
nodes1 <- data.frame(
name = c("x4", NA, NA),
val = c(1, 5, 2)
)
nodes2 <- data.frame(
name = c("x4", "x2", NA, NA, "x1", NA, NA),
val = c(3, 2, 2, 1, 1, 2, 7)
)
nodes3 <- data.frame(
name = c("x1", "x2", NA),
val = c(7, 4, 2)
)
nodes4 <- nodes1
nodes5 <- nodes2
nodes6 <- nodes1
edges <- data.frame(from = c(1, 1), to = c(2, 3))
edges1 <- data.frame(
from = c(1, 2, 2, 1, 5, 5),
to = c(2, 3, 4, 5, 6, 7)
)
# create the tbl_graphs
tg_1 <- tbl_graph(nodes = nodes1, edges = edges)
tg_2 <- tbl_graph(nodes = nodes2, edges = edges1)
tg_3 <- tbl_graph(nodes = nodes3, edges = edges)
tg_4 <- tbl_graph(nodes = nodes4, edges = edges)
tg_5 <- tbl_graph(nodes = nodes5, edges = edges1)
tg_6 <- tbl_graph(nodes = nodes6, edges = edges)
# put into list
myList <- list(tg_1, tg_2, tg_3, tg_4, tg_5, tg_6)
因此,我们可以看到 myList
中有 6 个 tidygraph
个对象。
检查每个元素,我们可以看到 3 个对象具有相同的 name
列(即 x4,NA,NA
).... 2 个对象具有相同的 name
列("x4", "x2", NA, NA, "x1", NA, NA
).. 剩下 1 个对象 (x1,x2,NA
).
使用一个小函数来获取同名列的计数:
# get a count of identical list elements based on `name` col
counts <- lapply(myList, function(x) {
x %>%
pull(name) %>%
paste0(collapse = "")
}) %>%
unlist(use.names = F) %>%
as_tibble() %>%
group_by(value) %>%
mutate(val = n():1) %>%
slice(1) %>%
arrange(-val)
为了清楚起见:
> counts
# A tibble: 3 × 2
# Groups: value [3]
value val
<chr> <int>
1 x4 NA NA 3
2 x4 x2 NA NA x1 NA NA 2
3 x1 x2 NA 1
我想根据 counts
对象中的 val
列重新排列 myList
中列表元素的顺序。
我想要的输出看起来像这样(我只是手动重新排序):
myList <- list(tg_1, tg_4, tg_6, tg_2, tg_5, tg_3)
有没有一种方法可以根据相同 name
列的数量自动重新排序我的列表?
更新:
所以我尝试的解决方案是执行以下操作:
ind <- map(myList, function(x){
x %>%
pull(name) %>%
replace_na("..") %>%
paste0(collapse = "")
}) %>%
unlist(use.names = F) %>%
as_tibble() %>%
mutate(ids = 1:n()) %>%
group_by(value) %>%
mutate(val = n():1) %>%
arrange(value) %>%
pull(ids)
# return new list of trees
myListNew <- myList[ind]
以上代码按 name
列和 returns 名为 ind
的索引对列表元素进行分组。然后我通过 ind
索引索引我的原始列表以重新排列我的列表。
但是,我仍然想找到一种方法来根据每个相同 name
变量的总量对新列表进行排序...我还没有弄清楚。
经过几个小时的测试,我终于有了一个可行的解决方案。
ind <- map(myList, function(x){
x %>%
pull(name) %>%
replace_na("..") %>%
paste0(collapse = "")
}) %>%
unlist(use.names = F) %>%
as_tibble() %>%
mutate(ids = 1:n()) %>%
group_by(value) %>%
mutate(val = n():1) %>%
arrange(value)
ind <- ind %>%
group_by(value) %>%
mutate(valrank = min(ids)) %>%
ungroup() %>%
arrange(valrank, value, desc(val)) %>%
pull(ids)
# return new list of trees
myListNew <- myList[ind]
以上代码按 name
字母顺序排列列表。然后我按名称分组并创建另一列对该行进行排名。然后我可以根据这个变量重新排列行。最后我按结果索引。