生成和求和矩阵

9

我是一个相对新手的R语言用户,所以请原谅我提出的这个相对简单的问题。

我的数据形式为

    1   2   3   4   5
A   0   1   1   0   0
B   1   0   1   0   1
C   0   1   0   1   0
D   1   0   0   0   0
E   0   0   0   0   1

A-E分别代表人员,1-5表示他们是否具有该品质的二进制。我需要制作一个A-E的矩阵,在这个矩阵中,如果A和B的品质1-5之和等于2(即他们至少分享一种品质),则单元格A,B=1。简单的5x5矩阵如下:

    A   B   C   D   E
A   1               
B   1   1           
C   1   0   1       
D   0   1   0   1   
E   0   1   0   0   1

我需要对整个矩阵进行求和(上面的结果为9)。由于我有数千个观测值,所以无法手动完成此操作。我相信只需要几行简单的代码就可以实现,但我没有足够的经验。
谢谢!
编辑:我已从一个.csv文件中导入了数据,其中包含1-5列作为变量,在真实数据中我有40个变量。A-E是大约2000个人的唯一ID观测值。我还想知道如何将其转换为矩阵,以执行您已经提供的好答案。谢谢!
3个回答

7
你可以在这里使用矩阵乘法。
out <- tcrossprod(m)
#   A B C D E
# A 2 1 1 0 0
# B 1 3 0 1 1
# C 1 0 2 0 0
# D 0 1 0 1 0
# E 0 1 0 0 1

如果需要,将对角线设置为1。
diag(out) <- 1

正如DavidA在评论中指出的那样,tcrossprod基本上是在执行m %*% t(m)

有几种方法可以计算sum,这里是其中之一

sum(out[upper.tri(out, diag=TRUE)] , na.rm=TRUE)

不用客气。如果您有每行数据,可以使用 rbind 将它们绑定在一起,就会形成一个矩阵。否则,如果您的数据是 data.frame,可以使用 as.matrix。如果这两种方法都不行,请您编辑一下问题,说明数据的存储方式。谢谢。 - user20650
谢谢,我已经在上面添加了编辑。我已经从一个.csv文件中导入了数据,并将(1-5)列作为变量,在真实数据中我有40个变量。A-E是大约2000个人的唯一ID观察值。我还想知道如何首先将其转换为矩阵,以执行您已经提供的优秀答案。 - ChrisDH
是的,包括列标题(变量)和二进制输出,生成一个 .csv 文件。 - ChrisDH
嗯...那么m <- as.matrix(yourdata)可以将其转换为矩阵吗?如果不行,您能否使用dput(yourdata[1:5, 1:5])发布一小部分数据。谢谢。 - user20650
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/75235/discussion-between-chrisdh-and-user20650。 - ChrisDH
显示剩余2条评论

1

如果您的方阵是 m,您可以使用 outer

f = Vectorize(function(u,v) any(colSums(m[c(u,v),])>1)+0L)

res = outer(1:ncol(m), 1:ncol(m), FUN=f)
colnames(res) = row.names(res) = rownames(m)

#  A B C D E
#A 1 1 1 0 0
#B 1 1 0 1 1
#C 1 0 1 0 0
#D 0 1 0 1 0
#E 0 1 0 0 1

数据:

m = structure(c(0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 
1, 0, 0, 0, 1, 0, 0, 1), .Dim = c(5L, 5L), .Dimnames = list(c("A", 
"B", "C", "D", "E"), NULL))

1

这个怎么样?(当然不像 tcrossprod 解决方案那么优雅):

d <- dim(m)
ind <- expand.grid(1:d[1],1:d[1])
M <- matrix(as.numeric(apply(cbind(m[ind[,2],],m[ind[,1]]), 1, 
+   function(x) sum(x[1:d[1]] == 1 & x[(d[1]+1):(d[1]*2)] == 1) >=1)), ncol = d[1])

rownames(M) = colnames(M) = rownames(m)
M
  A B C D E
A 1 1 1 0 0
B 1 1 0 1 1
C 1 0 1 0 0
D 0 1 0 1 0
E 0 1 0 0 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接