转向循环来应用

时间:2015-08-05 10:06:37

标签: r apply

我试图了解申请是如何运作的,但很难理解如何使用它。 我有一个名为 SSO9 的df帧,即172 * 92。它只有1:s或0:s作为元素。

Col1 Col2 Col3 ...
1      0    1
0      1    1
0      0    1
.
.

我现在想要在选择三列时采用每个排列并取出rowum。首先是第一列,第二列和第三列,然后取行和并将其保存在新的df中,然后是第一个和第四个,依此类推。这意味着这将在92选择3 = 125580列中重新开始。

ds=data.frame(rowSums(SSO9[,c(1,2,3)]))

for(i in 1:90){
  for(j in (i+1):91){ 
    for(k in (j+1):92){
    temp<-data.frame(rowSums(SSO9[,c(i,j,k)]))
    colnames(temp)<-(paste(colnames(SSO9[i]),colnames(SSO9[c(j)]),paste(colnames(SSO9[k]),sep=",")))
    ds=cbind(ds,temp) 
    rm(temp)
    }
  }
}
ds$rowSums.SSO9...c.1..2..3...<-NULL

这段代码工作但有点慢,所以我想尝试使用3 for for循环的应用insted,但我不知道如何使用apply,特别是当我想要所有的排列时。另外你可以看到我通过获取前三列的rowsum然后删除它来创建df ds ,只是为了获得正确的维度,但是可能有更好的方法来做到这一点。

1 个答案:

答案 0 :(得分:1)

我建议的第一件事是将输入存储为矩阵,因为它只有1和0,这些类型的数值运算通常在数据上比data.frames更高效。

以下是使用combn()apply()rowSums()完成此操作的方式:

set.seed(1);
NR <- 172; NC <- 92; SSO9 <- matrix(sample(0:1,NR*NC,replace=T),NR,dimnames=list(NULL,paste0('Col',1:NC)));
head(SSO9[,1:10]);
##      Col1 Col2 Col3 Col4 Col5 Col6 Col7 Col8 Col9 Col10
## [1,]    0    1    1    1    0    0    0    1    1     0
## [2,]    0    0    0    1    1    0    1    1    1     1
## [3,]    1    0    0    0    0    1    1    1    0     0
## [4,]    1    1    0    1    1    0    0    1    1     0
## [5,]    0    1    0    1    1    0    0    0    1     1
## [6,]    1    1    1    1    1    0    1    1    1     0
system.time({
    comb <- combn(ncol(SSO9),3);
    res <- apply(comb,2,function(cis) rowSums(SSO9[,cis]));
    colnames(res) <- apply(comb,2,function(cis) paste(colnames(SSO9)[cis],collapse=','));
});
##    user  system elapsed
##   3.422   0.203   3.626
dim(res);
## [1]    172 125580
head(res[,1:10]);
##      Col1,Col2,Col3 Col1,Col2,Col4 Col1,Col2,Col5 Col1,Col2,Col6 Col1,Col2,Col7 Col1,Col2,Col8 Col1,Col2,Col9 Col1,Col2,Col10 Col1,Col2,Col11 Col1,Col2,Col12
## [1,]              2              2              1              1              1              2              2               1               2               2
## [2,]              0              1              1              0              1              1              1               1               0               0
## [3,]              1              1              1              2              2              2              1               1               2               2
## [4,]              2              3              3              2              2              3              3               2               3               3
## [5,]              1              2              2              1              1              1              2               2               1               1
## [6,]              3              3              3              2              3              3              3               2               2               2

另请注意,这些是combinations,而不是permutations,因为顺序并不重要。