【问题标题】:Converting cross-sectional data into an adjacency matrix in R将横截面数据转换为R中的邻接矩阵
【发布时间】:2014-10-20 21:27:32
【问题描述】:

我正在尝试将横截面数据转换为邻接矩阵,因为我想分析某些变量与社交网络分析一起出现的频率。 如果经验性的例子对逻辑有所帮助,这基本上类似于让 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 个变量,因此即使使用循环或使用应用函数,它也会非常低效。

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

感谢您的帮助,

【问题讨论】:

    标签: r dataset adjacency-matrix


    【解决方案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
      }
    }
    

    【讨论】:

    • 效果很好,谢谢。第一个选项使用我的数据为 t3[2,2] 命令提供了“下标越界错误”,尽管没有使用您的模拟数据。但是第二个版本有效(m3c),我的数据是二分法的,所以这很好。非常感谢您的帮助,
    • @user3830805 如果这回答了问题,您应该检查复选标记,以免其他人不响应。如果答案是有益的,您可以点击向上箭头。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多