将 data.frame 转换为邻接矩阵以进行网络分析 (R)
Converting a data.frame to an adjacency matrix for network analysis (R)
我想将下面显示的数据转换为邻接矩阵,以便将其用于网络分析。
变量如下:
ccode1
:国家1的州号
ccode2
:国家2的州编号
year
- 观测年份
DR_at_1
- 第 2 方在第 1 方的外交代表级别(见下文)
DR_at_2
- 第 1 方在第 2 方的外交代表级别(见下文)
DE
- 第一方和第二方之间的任何外交交流(见下文)
version
- 数据集的当前版本
# A tibble: 6 x 7
ccode1 ccode2 year DR_at_1 DR_at_2 DE version
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2 20 1920 0 0 0 2006.
2 2 20 1925 0 0 0 2006.
3 2 20 1930 0 2 1 2006.
4 2 20 1935 2 2 1 2006.
5 2 20 1940 2 2 1 2006.
6 2 20 1950 9 9 1 2006.
我想要以下表示而不是这种表示:
country1
country2 1' 2' 3' 4' 5' 6'
1 0 1 0 0 0 0
2 1 0 1 0 0 0
3 0 0 0 0 1 1
4 1 0 1 0 1 1
5 0 1 0 0 0 1
6 0 0 1 0 1 0
请注意,此 table 的值是假设的。
我是 R 的新手,这就是为什么我对如何在这种情况下处理 'year' 变量感到困惑。我的直觉是邻接 table 应该每年单独构建,但我愿意接受其他建议。
邻接 table 的值应基于 country2/1 是否在 country1/2 有任何外交代表(DR_at_1 > 0
或 DR_at_2 > 0
)。
我使用的数据可以在以下网址以可复制的方式找到:http://www.correlatesofwar.org/data-sets/diplomatic-exchange
提前致谢!
方法
考虑到您已有的数据格式,这不是一项艰巨的任务。下面是一个使用特殊矩阵索引格式的示例 - 当通过提供另一个矩阵(索引矩阵)来选择矩阵中的元素时,通过(行,列)对指定每个元素。
要更好地理解这种索引格式,请阅读 help("[")
:
...
A third form of indexing is via a numeric matrix with the one
column for each dimension: each row of the index matrix then
selects a single element of the array, and the result is a vector.
...
例子
给定一个玩具数据集:
df <- data.frame(code1=1:6, code2=c(2,3,2,2,6,1), year=1990+1:6,
DR_at_1=c(0,0,0,2,2,9), DR_at_2=c(0,0,2,2,2,9))
df
code1 code2 year DR_at_1 DR_at_2
1 1 2 1991 0 0
2 2 3 1992 0 0
3 3 2 1993 0 2
4 4 2 1994 2 2
5 5 6 1995 2 2
6 6 1 1996 9 9
我们可以获得相关边的列表:
edges <- df[df$DR_at_1 > 0 | df$DR_at_2 > 0,]
edges <- cbind(as.character(edges$code1), as.character(edges$code2))
edges <- rbind(edges, edges[,2:1]) # for each edge (u,v) add a symetric edge (v,u)
edges
[,1] [,2]
[1,] "3" "2"
[2,] "4" "2"
[3,] "5" "6"
[4,] "6" "1"
[5,] "2" "3"
[6,] "2" "4"
[7,] "6" "5"
[8,] "1" "6"
首先构建一个空的邻接矩阵,其中国家代码作为行名和列名:
codes <- unique(c(df$code1, df$code2)) # All available country codes
A <- matrix(0, nrow=length(codes), ncol=length(codes), dimnames=list(codes, codes))
A
1 2 3 4 5 6
1 0 0 0 0 0 0
2 0 0 0 0 0 0
3 0 0 0 0 0 0
4 0 0 0 0 0 0
5 0 0 0 0 0 0
6 0 0 0 0 0 0
最后将需要的边添加到矩阵中:
A[edges] <- 1
A
1 2 3 4 5 6
1 0 0 0 0 0 1
2 0 0 1 1 0 0
3 0 1 0 0 0 0
4 0 1 0 0 0 0
5 0 0 0 0 0 1
6 1 0 0 0 1 0
年份变量
一般来说,关于如何处理年份变量的问题是关于问题的上下文,而不是关于编程。您应该根据您对问题的先验信息来决定这一点。
然后,如果你想有一个单独的按年划分的邻接矩阵,在边缘选择阶段添加另一个过滤步骤:
# Get a list of edges
edges <- df[(df$DR_at_1 > 0 | df$DR_at_2 > 0) & df$year == 1990,]
我想将下面显示的数据转换为邻接矩阵,以便将其用于网络分析。
变量如下:
ccode1
:国家1的州号ccode2
:国家2的州编号year
- 观测年份DR_at_1
- 第 2 方在第 1 方的外交代表级别(见下文)DR_at_2
- 第 1 方在第 2 方的外交代表级别(见下文)DE
- 第一方和第二方之间的任何外交交流(见下文)version
- 数据集的当前版本
# A tibble: 6 x 7
ccode1 ccode2 year DR_at_1 DR_at_2 DE version
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2 20 1920 0 0 0 2006.
2 2 20 1925 0 0 0 2006.
3 2 20 1930 0 2 1 2006.
4 2 20 1935 2 2 1 2006.
5 2 20 1940 2 2 1 2006.
6 2 20 1950 9 9 1 2006.
我想要以下表示而不是这种表示:
country1
country2 1' 2' 3' 4' 5' 6'
1 0 1 0 0 0 0
2 1 0 1 0 0 0
3 0 0 0 0 1 1
4 1 0 1 0 1 1
5 0 1 0 0 0 1
6 0 0 1 0 1 0
请注意,此 table 的值是假设的。
我是 R 的新手,这就是为什么我对如何在这种情况下处理 'year' 变量感到困惑。我的直觉是邻接 table 应该每年单独构建,但我愿意接受其他建议。
邻接 table 的值应基于 country2/1 是否在 country1/2 有任何外交代表(DR_at_1 > 0
或 DR_at_2 > 0
)。
我使用的数据可以在以下网址以可复制的方式找到:http://www.correlatesofwar.org/data-sets/diplomatic-exchange
提前致谢!
方法
考虑到您已有的数据格式,这不是一项艰巨的任务。下面是一个使用特殊矩阵索引格式的示例 - 当通过提供另一个矩阵(索引矩阵)来选择矩阵中的元素时,通过(行,列)对指定每个元素。
要更好地理解这种索引格式,请阅读 help("[")
:
...
A third form of indexing is via a numeric matrix with the one
column for each dimension: each row of the index matrix then
selects a single element of the array, and the result is a vector.
...
例子
给定一个玩具数据集:
df <- data.frame(code1=1:6, code2=c(2,3,2,2,6,1), year=1990+1:6,
DR_at_1=c(0,0,0,2,2,9), DR_at_2=c(0,0,2,2,2,9))
df
code1 code2 year DR_at_1 DR_at_2
1 1 2 1991 0 0
2 2 3 1992 0 0
3 3 2 1993 0 2
4 4 2 1994 2 2
5 5 6 1995 2 2
6 6 1 1996 9 9
我们可以获得相关边的列表:
edges <- df[df$DR_at_1 > 0 | df$DR_at_2 > 0,]
edges <- cbind(as.character(edges$code1), as.character(edges$code2))
edges <- rbind(edges, edges[,2:1]) # for each edge (u,v) add a symetric edge (v,u)
edges
[,1] [,2]
[1,] "3" "2"
[2,] "4" "2"
[3,] "5" "6"
[4,] "6" "1"
[5,] "2" "3"
[6,] "2" "4"
[7,] "6" "5"
[8,] "1" "6"
首先构建一个空的邻接矩阵,其中国家代码作为行名和列名:
codes <- unique(c(df$code1, df$code2)) # All available country codes
A <- matrix(0, nrow=length(codes), ncol=length(codes), dimnames=list(codes, codes))
A
1 2 3 4 5 6
1 0 0 0 0 0 0
2 0 0 0 0 0 0
3 0 0 0 0 0 0
4 0 0 0 0 0 0
5 0 0 0 0 0 0
6 0 0 0 0 0 0
最后将需要的边添加到矩阵中:
A[edges] <- 1
A
1 2 3 4 5 6
1 0 0 0 0 0 1
2 0 0 1 1 0 0
3 0 1 0 0 0 0
4 0 1 0 0 0 0
5 0 0 0 0 0 1
6 1 0 0 0 1 0
年份变量
一般来说,关于如何处理年份变量的问题是关于问题的上下文,而不是关于编程。您应该根据您对问题的先验信息来决定这一点。
然后,如果你想有一个单独的按年划分的邻接矩阵,在边缘选择阶段添加另一个过滤步骤:
# Get a list of edges
edges <- df[(df$DR_at_1 > 0 | df$DR_at_2 > 0) & df$year == 1990,]