让我们创建一个仅有三个项目的虚假测试(n = 3)。人们可以回答每个项目的权利(1)或错误的(0)。测试结果只有八种可能性,即所有1,全0和其间的一些组合。以下代码可用于模拟此场景:
n=3; m=0
while(m!=2^n) {
tmat = t(sapply(1:(10*2^n), function(x) sample(c(0,1), n, replace=T)))
pats = apply(tmat, 1, paste, collapse="/")
pats = unique(pats)
m = length(pats)
}
xmat = matrix(as.numeric(unlist(strsplit(pats, "/"))), ncol=n, nrow=m, byrow=T)
但是,现在我需要对xmat行进行排序,结果应如下所示:
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 1 0 0 1
[3,] 0 1 0 1
[4,] 0 0 1 1
[5,] 1 1 0 2
[6,] 1 0 1 2
[7,] 0 1 1 2
[8,] 1 1 1 3
我使用此代码获得上述结果:
# create the fourth column which is the total score
xmat = cbind(xmat, rowSums(xmat))
# order by the 4th column, then 3rd column, then 2nd column.
xmat = xmat[order(xmat[,4], xmat[,3], xmat[,2]),]
我的问题是我将来会有任意数量的列n(在这种情况下n = 3)。我无法在代码中手动输入n-1个术语来订购矩阵,如下所示:
xmat = xmat[order(xmat[,n+1], xmat[,n], xmat[,n-1]), ... , xmat[,2])
有最简单的方法可以做最后一步吗?
提前谢谢!
答案 0 :(得分:4)
我认为应该这样做:
xmat[do.call(order, rev(split(xmat, col(xmat)))), ]
其中:
split(xmat, col(xmat)
将您的矩阵拆分为列的列表rev
重新排序列表(最后一列)do.call
在列表中调用order