R - построить матрицу смежности на основе другой матрицы смежности
У меня есть данные, которые похожи на эти две матрицы смежности:
data1999 <- data.frame(node1=c("A", "A", "B", "D", "B", "C", "D"),
node2=c("A", "A", "D", "B", "B", "C", "D"),
link=c(1, 1, 1, 1, 1, 1, 1),
stringsAsFactors = FALSE)
adj.m1999 <- reshape2::acast(data1999, node1 ~ node2)
> adj.m1999
A B C D
A 2 0 0 0
B 0 1 0 1
C 0 0 1 0
D 0 1 0 1
data2000 <- data.frame(node1=c("A", "A", "B", "C", "D", "C", "D"),
node2=c("A", "A", "B", "C", "D", "D", "C"),
link=c(1, 1, 1, 1, 1, 1, 1),
stringsAsFactors = FALSE)
adj.m2000 <- reshape2::acast(data2000, node1 ~ node2)
> adj.m2000
A B C D
A 2 0 0 0
B 0 1 0 0
C 0 0 1 1
D 0 0 1 1
Обратите внимание, что в 1999 году узлы D и B имеют ссылку.
Обратите внимание, что в 2000 году узлы D и C имеют ссылку.
Основываясь на этой информации, я хочу построить новую матрицу смежности (со всеми узлами моих данных 2000 года), в которой BD и DB имеют значение 1, а остальные - ноль:
> result
A B C D
A 0 0 0 0
B 0 0 1 0
C 0 1 0 0
D 0 0 0 0
В моих реальных данных данные 1999 года могут иметь дополнительные узлы, которые не возвращаются в 2000 году и наоборот.
Есть идеи?
1 ответ
В теории графов произведение двух матриц смежности m1 и m2 дает в позиции (i,j) количество способов пройти от i до j, пройдя сначала через m1, а затем через m2. Это связано с тем, что вы хотите, но не совсем так, как если бы мы adj.m1999 %*% adj.m2000
, мы получаем:
A B C D
A 4 0 0 0
B 0 1 1 1
C 0 0 1 1
D 0 1 1 1
Так, например, вы можете перейти от C к D одним способом, и это будет C -> C, за которым следует C -> D. В вашем примере вы не учитываете ссылки (или ребра), которые находятся на Диагональ, а также ваш график не направлены, поэтому, если я правильно понимаю, что вы хотите, вы могли бы сделать:
## First make sure that you have in adj.m1999 only nodes that appear in adj.m2000:
adj.m1999 = adj.m1999[row.names(adj.m1999) %in% row.names(adj.m2000),colnames(adj.m1999) %in% colnames(adj.m2000)]
## Then turn both diagonals into zeros:
diag(adj.m1999) = 0
diag(adj.m2000) = 0
## Finally, get the sum of the two products
res = adj.m1999 %*% adj.m2000 + adj.m2000 %*% adj.m1999
A B C D
A 0 0 0 0
B 0 0 1 0
C 0 1 0 0
D 0 0 0 0