2016-12-01 63 views
0

我有两个R表(女性和男性)与存在缺勤数据。我想在它们之间进行两两比较(逐行)以找出每对之间不共享的细胞数量(即细胞总数等于女性中的1,而不是男性中,反之亦然) 。交叉产品的对面:如何从两个矩阵的交集创建一个新的矩阵?

我知道交叉产品(%*%)与我所需要的相反。它创建了一个新的矩阵,其中包含男性和女性之间共享单元格的总和(即两个单元格的总和等于1)。

下面是一个例子数据集:

females <- as.data.frame(matrix(c(0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1), nrow=5, byrow=T)) 
males <- as.data.frame(matrix(c(1,0,0,1,1,0,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1), nrow=5, byrow=T)) 
rownames(females) <-c ("female_1","female_2","female_3","female_4","female_5") 
rownames(males) <-c ("male_1","male_2","male_3","male_4","male_5") 

所以,如果我做跨产品

as.matrix(females) %*% t(as.matrix(males)) 

我得到这个

  male_1 male_2 male_3 male_4 male_5 
female_1  2  2  1  2  1 
female_2  1  2  0  2  0 
female_3  2  1  3  2  3 
female_4  3  3  2  4  2 
female_5  3  2  3  3  3 

但我需要这个(仅第一行显示)

  male_1 male_2 male_3 male_4 male_5 
female_1  1  1  3  2  3 
. 
. 

实际上,我的数据集不是对称的(我有47位女性和32位男性)。

感谢您的帮助!

+0

您可以从数据帧看到female_1有“0”的位置[1,1]和male_1有“1 “在位置[1,1]。在两个数据集中的所有5列中,这是唯一一个这一对之间存在“不匹配”的地方。因此,总共有1个单元格,这个female_1/male_1两两比较符合我的条件。那有意义吗? – pbc

+0

它在任何意义上都不是一个“交集”,而是映射到“产品空间”。为矩阵对象提供n-m结果的两个函数是'outer'和'kronecker',但要让它们正常工作,通常需要精细地编写代码以获取能够提供适当尺寸结果的函数。 –

+0

除非我错过了一些东西,'ncol(女性) - tcrossprod(!女性,!男性) - tcrossprod(as.matrix(女性),as.matrix(男性))似乎是正确的 –

回答

1

建立一个对象,以接收结果:呼吁

xy <- matrix(NA, nrow(females), nrow(males)) 
for (x in 1:nrow(females)){ 
     for(y in 1:nrow(males)){ 
       xy[x,y] <- sum(females[x, 1:ncol(females)] != males[y,1:ncol(males)])}} 

应与嵌套sapply已经做的很好,可能是有点清洁,因为没有需要有一个单独的“设置”,(但只有一点点清洁和流行的神话相反没有任何更快):

xy <- sapply(1:nrow(females) , 
       function(x) sapply(1:nrow(males) , 
        function(y) sum(females[x, 1:ncol(females)] != males[y,1:ncol(males)]))) 
xy 
#----- 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 3 2 1 1 
[2,] 1 1 4 1 3 
[3,] 3 5 0 3 1 
[4,] 2 2 3 0 2 
[5,] 3 5 0 3 1 

dimnames(xy) <- list(rownames(females), rownames(males)) 
+0

谢谢,@ 42-!有没有办法保留行和列的名称(如在跨产品示例中),以便以后可以使用它们? – pbc

+0

将dimname添加到矩阵中非常简单。请参阅'?dimnames'的帮助页面,因为我确信分配函数也被描述。如果使用for-loop方法,也可以在“设置”步骤中完成它。 –

+0

优秀@ 42-!再次感谢! – pbc

0
inverseCross <- function(females, males){ 
inverse <- data.frame(a=integer(), b=integer(), c=integer(), d=integer(), e=integer()) 
tempRow <- NULL 
for(i in 1:nrow(females)){ 
for(j in 1:nrow(males)){ 
sum <- 0 
for(k in 1: ncol(males)){ 
if(females[i,k] != males[j,k]){ 
sum <- sum + 1 
} 
} 
tempRow <- c(tempRow, sum) 
} 
inverse[i,] <- tempRow 
} 
colnames(inverse) <- rownames(males) 
rownames(inverse) <- rownames(females) 
inverse 
} 
+0

我怀疑这会运行在那一刻。在R中,换行符(或分号)在语法上至关重要。 –

+0

哦,我测试了它,这工作正常 –

+0

inverseCross < - function(female,male){inverse < - data。对于(i in 1:nrow(女性)){ tempRow < - NULL(0,1,2,...)的帧(a =整数(),b =整数(),c =整数(),d =整数(),e =如果(雌性[i,k]!=雄性[j,k])(012), { 总和< - 总和+ 1 } } tempRow < - C(tempRow,总和) } 逆[I,] < - tempRow } colnames(逆)< - rownames(雄性) rownames(逆)< - rownames(女性) inverse } –