2016-11-15 161 views
0

我有频率中的R像这样的数据帧对称关系的矩阵:R:从频率数据帧

V1 V2 V3 V4 
row1 1 2 0 1 
row2 0 6 0 3 
row3 3 0 0 0 
row4 0 0 2 0 
row5 4 1 0 0 
row6 3 0 1 1 
(more rows) 

a<-as.data.frame(matrix(c(1,2,0,1,0,6,0,3,3,0,0,0,0,0,2,0,4,1,0,0,3,0,1,1),byrow=T,ncol=4)) 

我想的函数来计算,对于每一行,列之间的匹配,其中这两个值均> 0,所以我得到了V1-V4的关系矩阵,如下所示:

V1 V2 V3 V4 
V1 
V2 2 
V3 1 0 
V4 2 2 1 

是否有一些方便的功能可用?或者我应该怎么做?

回答

1

这里是使用combn,sapplyrowSums的基本R方法。

# get the pairwise combination of variables 
varComb <- combn(names(df), 2) 
varComb 
    [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] "V1" "V1" "V1" "V2" "V2" "V3" 
[2,] "V2" "V3" "V4" "V3" "V4" "V4" 

# get the counts 
counts <- sapply(seq_len(ncol(varComb)), 
       function(i) sum(rowSums(df[,varComb[,i]] > 0) == 2)) 

这里,变量组合用于子集的数据帧,这是基于该值是否是大于0的行被SUMED在一起并进行计数转换为一个逻辑矩阵(使用sum )根据结果是否等于2. sapply允许我们将此计数应用于varComb中存在的每对变量。

# put these into a data frame 
setNames(data.frame(t(varComb), counts), c("var1", "var2", "counts")) 
    var1 var2 counts 
1 V1 V2  2 
2 V1 V3  1 
3 V1 V4  2 
4 V2 V3  0 
5 V2 V4  2 
6 V3 V4  1 

把这些结果在一起,我们可以使用setNames,这使我们能够创建一个数据帧,并在同一行申请名称的变量。


把这一结果为矩阵,你可以使用cbind和矩阵子集:

# construct empty matrix 
tempMat <- matrix(NA, 4, 4) 

# fill it in 
tempMat[cbind(as.integer(substr(dfNew$var2, 2, 2)), 
       as.integer(substr(dfNew$var1, 2, 2)))] <- dfNew$counts 

tempMat 
    [,1] [,2] [,3] [,4] 
[1,] NA NA NA NA 
[2,] 2 NA NA NA 
[3,] 1 0 NA NA 
[4,] 2 2 1 NA 

as.integersubstr提取行并在其中放置值的列,cbind将这个输出成一个用于矩阵子化的矩阵。

+0

这是一个整洁的想法,但有没有办法将输出作为矩阵? – Zwentibold

0

有点摆弄在这里后,好就是我想出了:

a<-as.data.frame(matrix(c(1,2,0,1,0,6,0,3,3,0,0,0,0,0,2,0,4,1,0,0,3,0,1,1),byrow=T,ncol=4)) 
a[a>0]<-1 
a<-t(a)  
mat<-outer(1:nrow(a), 1:nrow(a), FUN=Vectorize(function(x,y) sum(a[x,]!=0 & a[y,]!=0))) 
mat[upper.tri(mat,diag=T)] <- 0 

不漂亮,但它似乎工作。

+1

一个变体,'t(a> 0)%*%(a> 0)* lower.tri(matrix(,ncol(a),ncol(a)))'似乎也适用。不等式的真/假在乘法中被视为1/0。 – Frank