将有向从属矩阵转换为边列表
convert directed affiliation matrix to edge list
我有一个定向从属关系矩阵,我想将其转换为边列表。矩阵如下所示:
State WarID Initiator
A 1 1
B 1 0
A 2 1
C 2 0
D 2 0
B 3 1
C 3 1
D 3 0
其中“State”是国家名称,“WarID”是 war 的唯一标识符,“Initiator”是虚拟变量,如果国家发起 war.如果两个状态共享相同的“WarID”但具有不同的“Initiator”值,则它们之间存在边缘。
我想把上面的从属关系矩阵改成这样的边列表:
Initiator Target WarID
A B 1
A C 2
A D 2
B D 3
C D 3
我知道如何将基本的从属关系矩阵更改为边列表,但我在保留“定向网络”组件方面遇到了困难。如果有人能告诉我如何在 R 中有效地执行此操作,我将不胜感激(我有一个非常大的隶属关系矩阵)。
这个有用吗:
> library(dplyr)
> df %>% group_by(WarID) %>% filter(Initiator == 1) %>%
+ inner_join(df %>% group_by(WarID) %>% filter(Initiator == 0), by = ('WarID')) %>% rename(Target = State.y, Initiator = State.x ) %>%
+ select(1,4,2)
# A tibble: 5 x 3
# Groups: WarID [3]
Initiator Target WarID
<chr> <chr> <dbl>
1 A B 1
2 A C 2
3 A D 2
4 B D 3
5 C D 3
>
使用的数据:
> dput(df)
structure(list(State = c("A", "B", "A", "C", "D", "B", "C", "D"
), WarID = c(1, 1, 2, 2, 2, 3, 3, 3), Initiator = c(1, 0, 1,
0, 0, 1, 1, 0)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -8L), spec = structure(list(cols = list(
State = structure(list(), class = c("collector_character",
"collector")), WarID = structure(list(), class = c("collector_double",
"collector")), Initiator = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
>
使用 tidyverse 你可以做:
library(tidyverse)
df %>%
group_by(WarID) %>%
summarise(Target = list(State[Initiator==0]),
Initiator = list(State[Initiator==1]), .groups='drop') %>%
unnest(c(Initiator, Target)) %>%
rev() # Just to reverse the ordering, otherwise not necessary
# A tibble: 5 x 3
Initiator Target WarID
<chr> <chr> <int>
1 A B 1
2 A C 2
3 A D 2
4 B D 3
5 C D 3
您可以使用 tapply
按 WarID
和 Initiator
对数据进行分组,并为每个 WarID
创建一个 expand.grid
。只是 rbind
结果。
FUN <- function(d) {
r <- with(d, tapply(State, list(WarID, Initiator), I))
r <- lapply(1:nrow(r), function(i) cbind(expand.grid(rev(r[i, ])), i))
r <- setNames(do.call(rbind, r), c("Initiator", "Target", "WarID"))
r
}
FUN(d)
# Initiator Target WarID
# 1 A B 1
# 2 A C 2
# 3 A D 2
# 4 B D 3
# 5 C D 3
请注意,我使用了您指定的连续 WarID
s。
数据:
d <- structure(list(State = c("A", "B", "A", "C", "D", "B", "C", "D"
), WarID = c(1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), Initiator = c(1L,
0L, 1L, 0L, 0L, 1L, 1L, 0L)), class = "data.frame", row.names = c(NA,
-8L))
我有一个定向从属关系矩阵,我想将其转换为边列表。矩阵如下所示:
State WarID Initiator
A 1 1
B 1 0
A 2 1
C 2 0
D 2 0
B 3 1
C 3 1
D 3 0
其中“State”是国家名称,“WarID”是 war 的唯一标识符,“Initiator”是虚拟变量,如果国家发起 war.如果两个状态共享相同的“WarID”但具有不同的“Initiator”值,则它们之间存在边缘。
我想把上面的从属关系矩阵改成这样的边列表:
Initiator Target WarID
A B 1
A C 2
A D 2
B D 3
C D 3
我知道如何将基本的从属关系矩阵更改为边列表,但我在保留“定向网络”组件方面遇到了困难。如果有人能告诉我如何在 R 中有效地执行此操作,我将不胜感激(我有一个非常大的隶属关系矩阵)。
这个有用吗:
> library(dplyr)
> df %>% group_by(WarID) %>% filter(Initiator == 1) %>%
+ inner_join(df %>% group_by(WarID) %>% filter(Initiator == 0), by = ('WarID')) %>% rename(Target = State.y, Initiator = State.x ) %>%
+ select(1,4,2)
# A tibble: 5 x 3
# Groups: WarID [3]
Initiator Target WarID
<chr> <chr> <dbl>
1 A B 1
2 A C 2
3 A D 2
4 B D 3
5 C D 3
>
使用的数据:
> dput(df)
structure(list(State = c("A", "B", "A", "C", "D", "B", "C", "D"
), WarID = c(1, 1, 2, 2, 2, 3, 3, 3), Initiator = c(1, 0, 1,
0, 0, 1, 1, 0)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -8L), spec = structure(list(cols = list(
State = structure(list(), class = c("collector_character",
"collector")), WarID = structure(list(), class = c("collector_double",
"collector")), Initiator = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
>
使用 tidyverse 你可以做:
library(tidyverse)
df %>%
group_by(WarID) %>%
summarise(Target = list(State[Initiator==0]),
Initiator = list(State[Initiator==1]), .groups='drop') %>%
unnest(c(Initiator, Target)) %>%
rev() # Just to reverse the ordering, otherwise not necessary
# A tibble: 5 x 3
Initiator Target WarID
<chr> <chr> <int>
1 A B 1
2 A C 2
3 A D 2
4 B D 3
5 C D 3
您可以使用 tapply
按 WarID
和 Initiator
对数据进行分组,并为每个 WarID
创建一个 expand.grid
。只是 rbind
结果。
FUN <- function(d) {
r <- with(d, tapply(State, list(WarID, Initiator), I))
r <- lapply(1:nrow(r), function(i) cbind(expand.grid(rev(r[i, ])), i))
r <- setNames(do.call(rbind, r), c("Initiator", "Target", "WarID"))
r
}
FUN(d)
# Initiator Target WarID
# 1 A B 1
# 2 A C 2
# 3 A D 2
# 4 B D 3
# 5 C D 3
请注意,我使用了您指定的连续 WarID
s。
数据:
d <- structure(list(State = c("A", "B", "A", "C", "D", "B", "C", "D"
), WarID = c(1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), Initiator = c(1L,
0L, 1L, 0L, 0L, 1L, 1L, 0L)), class = "data.frame", row.names = c(NA,
-8L))