将横截面数据转换为R中的邻接矩阵

时间:2014-10-20 21:27:33

标签: r dataset adjacency-matrix

我正在尝试将横截面数据转换为邻接矩阵,因为我想分析某些变量与社交网络分析一起出现的频率。     如果经验实例有助于逻辑,它基本上类似于向4个人提供三个对象的选择;他们可以选择0到3个对象。我想分析一起选择不同对象的常见程度,并将其视为偏好网络。

数据设置为横截面数据,如下:

ID1 <- c(1,0,0)
ID2 <- c(1,0,1)
ID3 <- c(1,1,1)
ID4 <- c(0,0,0)
IDs <- c("1","2","3","4")
df <- data.frame(rbind(ID1, ID2, ID3, ID4))
df <- cbind(IDs, df)
colnames(df) <- c("ID", "Var1", "Var2", "Var3")

我想为Var1,Var2和Var3创建加权邻接矩阵,每个单元格包含两个变量在观察值中一起出现的总次数。

所以我考虑的基本程序是为每一行创建一个单独的矩阵(每个ID号),每个单元格用1或0表示ID是否存在两个变量。然后将这些矩阵一起添加,因此最终矩阵给出了联合出现的总数。

我一直在环顾四周,并没有完全正确。我想过使用外部,但它需要按顺序为每个列工作。这个答案非常接近,但我不确定他们是如何将这些值加在一起的。我最终得到了一个矩阵列表,但这些值与初始数据不符 - Convert categorical data in data frame to weighted adjacency matrix。这个答案也很接近,尽管它似乎有不同类型的数据。它给了我一个基于ID的邻接矩阵 - http://r.789695.n4.nabble.com/Conversion-to-Adjacency-Matrix-td794102.html

这是一个非常混乱的代码,为一次观察手动创建一个矩阵,这样你就可以了解我的目标(使用代表第一个ID观察的向量)

ID1 <- c(1,0,0)

var1 <- ID1[[1]]
var2 <- ID1[[2]]
var3 <- ID1[[3]]
onetwo <- var1 * var2
onethree <- var1 * var3
twothree <- var2 * var3
oneone <- var1 * var1
twotwo <- var2 * var2
threethree <- var3 * var3
rows1 <- rbind(oneone, onetwo, onethree)
rows2 <- rbind(onetwo, twotwo, twothree)
rows3 <- rbind(onethree, twothree, threethree)
df2 <- cbind(rows1, rows2, rows3)

这显然不太理想,我的实际数据集有198个观察值和33个变量,因此即使使用循环或使用apply函数,它也会非常低效。

我无法判断我是否比这更困难,或者如果我试图强迫我的数据做一些不应该做的事情。但如果有人之前遇到过这种任务,请告诉我。有没有办法直接创建所需的邻接矩阵?我应该首先将其转移到边缘列表中,并且有一个很好的方法吗?是否有代码可以使第一步(为数据帧的每一行创建矩阵)更有效?

感谢您的帮助,

1 个答案:

答案 0 :(得分:1)

我不确定我是否理解这个问题,但这是你想要的吗?

nc=33
nr=198
m3<-matrix(sample(0:1,nc*nr,replace=TRUE),nrow=nr)
df3<-data.frame(m3)
m3b <-matrix(0,nrow=nc,ncol=nc)
for(i in seq(1,nc)) {
  for (j in seq(1,nc)) {
    t3<-table(df3[,i],df3[,j])
    m3b[i,j] = t3[2,2] # t3[2,2] contains the count of df3[,i] = df3[,j] = 1
    # or
    # t3 = sum(df3[,i]==df3[,j] & df3[,i] == 1)
    # m3b[i,j] = t3
  }
}

或者,如果你想要产品的总和,如果一切都是1或0,那么产生相同的结果

m3c <-matrix(0,nrow=nc,ncol=nc)
for(i in seq(1,nc)) {
  for (j in seq(1,nc)) {
    sv=0
    for (k in seq(1,nr)) {
      vi = df3[k,i]
      vj = df3[k,j]
      sv=sv+vi*vj      
    }
    m3c[i,j] = sv
  }
}