我试图了解申请是如何运作的,但很难理解如何使用它。 我有一个名为 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 ,只是为了获得正确的维度,但是可能有更好的方法来做到这一点。
答案 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,因为顺序并不重要。