我对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&的任何质量1-5的总和,则单元格A,B = 1。 B总和为2.(如果它们共享至少一种质量)。简单的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是对人的唯一ID观察,大约2000.我还想知道如何首先将其转换为矩阵,以便执行您已经提供的优秀答案。谢谢!
答案 0 :(得分: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
l的几种方法是一个
sum(out[upper.tri(out, diag=TRUE)] , na.rm=TRUE)
答案 1 :(得分:1)
如果outer
是您的方阵,您可以使用m
:
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))
答案 2 :(得分: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