在行和列

时间:2017-01-23 17:27:25

标签: r matrix adjacency-matrix sna

我有一个矩阵,代表各种工作之间的流动性:

jobnames <-  c("job 1","job 2","job 3","job 4","job 5","job 6","job 7")
jobdat <- matrix(c(
5, 5, 5, 0, 0, 5, 5,
5, 5, 2, 5, 5, 1, 5,
1, 5, 5, 5, 0, 0, 1,
1, 0, 5, 5, 8, 0, 1,
0, 5, 0, 0, 5, 5, 1,
0, 0, 5, 5, 0, 5, 5,
0, 1, 0, 0, 5, 1, 5
           ), 
           nrow = 7, ncol = 7, byrow = TRUE,
           dimnames = list(jobnames,jobnames
                ))

这被视为社交网络分析中的定向加权邻接矩阵。网络的方向是从行到列:因此,移动性定义为从作业行到作业列。对角线是相关的,因为可以在另一家公司改变相同的工作。

我需要根据预先列出的列表折叠此矩阵 包含应合并的作业的索引:

group.list  <-  list(grp1=c(1,2) ,grp2 =c(3,4))

现在,由于它是一个邻接矩阵,它与另一个有点不同。关于如何折叠我已经&#39;在这里和其他地方找到行和列的崩溃必须是同时的。有些工作根本没有分组。所以这个例子的结果应该是这样的:

group.jobnames <-  c("job 1 and 2","job 3 and 4","job 5","job 6","job 7")

 group.jobdat <- matrix(c(
            20,12,5,6,10,
            7,17,8,0,2,
            5,0,5,5,1,
            0,10,0,5,5,
            1,0,5,1,5
            ),
           nrow = 5, ncol = 5, byrow = TRUE,
           dimnames = list(group.jobnames,group.jobnames
                ))

此示例将两个第一个作业分组,然后分组接下来的两个,但在我的实际数据中,它可以是(索引)作业的任意组合,以及每个组中的任意数量的作业。所以工作[1,7]可以是一组,而工作[2,3,6]可以是另一组,而工作4或5不是分组。或任何其他组合。

感谢您的时间,

1 个答案:

答案 0 :(得分:1)

我相信在预期的输出和group.list定义中存在一些拼写错误。如果我的解释是正确的,这是一个解决方案。

这是一个新的group.list,以符合所需输出的名称。在此版本中,组2映射到1,组4映射到3,这符合group.jobs中的文本。

group.list <- list(grp1=c(1, 3), grp2=c(2, 4))

鉴于此列表,构建分组向量

# initial grouping
groups <- seq_len(ncol(jobdat))
# map elements of second list item to values of first list item
groups[match(group.list[["grp2"]], groups)] <- group.list[["grp1"]]

groups
[1] 1 1 3 3 5 6 7

所以,现在第1组和第2组与3和4相同。现在,我们使用rowsum和几个转置来计算输出。

myMat <- t(rowsum(t(rowsum(jobdat, groups)), groups))
# add the group names
dimnames(myMat) <- list(group.jobnames,group.jobnames)

myMat
            job 1 and 2 job 3 and 4 job 5 job 6 job 7
job 1 and 2          20          12     5     6    10
job 3 and 4           7          20     8     0     2
job 5                 5           0     5     5     1
job 6                 0          10     0     5     5
job 7                 1           0     5     1     5

在回应下面的OP评论时,分组意图在列表元素内,而不是我最初解释的列表元素之间的相应位置。为了实现这种形式的分组,replaceReduce的重复喂养将完成任务。 使用group.list作为问题,

group.list <- list(grp1=c(1, 2), grp2=c(3, 4))

groups <- Reduce(function(x, y) replace(x, x[x %in% y], min(y)),
                 c(list(groups), unname(group.list)))
groups
[1] 1 1 3 3 5 6 7

这里,replace采用原始分组,在group.list中的一个向量中找到分组中的元素,并用该向量的最小值替换它们。 Reduce函数在原始组变量上重复应用此操作,但在每次迭代中修改它除外。

使用此结果,我们使用上述转置和rowsum来获取

myMat
            job 1 and 2 job 3 and 4 job 5 job 6 job 7
job 1 and 2          20          12     5     6    10
job 3 and 4           7          20     8     0     2
job 5                 5           0     5     5     1
job 6                 0          10     0     5     5
job 7                 1           0     5     1     5