我的数据帧的频率如下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))
我想要一个函数来计算每一行的列之间的匹配,其中两个值都是&gt; 0,所以我得到了V1-V4的关系矩阵,如下所示:
V1 V2 V3 V4
V1
V2 2
V3 1 0
V4 2 2 1
是否有一些方便的功能?或者我该怎么做?
答案 0 :(得分:1)
以下是使用combn
,sapply
和rowSums
的基本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将其转换为逻辑矩阵。这些行一起被计算并计算(使用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.integer
和substr
提取要放置值的行和列,cbind
将此输出转换为矩阵,用于矩阵子设置。
答案 1 :(得分: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
不漂亮,但似乎有用。