R对角矩阵误差

时间:2018-03-02 10:24:25

标签: r diagonal permute

我有以下类型的数据框

   A    B   C   D
   1    0   1   10
   0    2   1   15
   1    1   0   11

我想要以下输出

    A   B   C   D
    1   0   1   10
    1   1   0   11
    0   2   1   15

我试过这段代码

 require(permute)
 z <- apply(permute::allPerms(1:nrow(DF)), 1, function(x){
  mat <- as.matrix(DF,2:ncol(DF)])
 if(all(diag(mat[x,]) == rep(1,nrow(DF)))){
 return(df[x,])} })

我无法获得所需的输出 (上述代码的链接 - Arrange data frame in a specific way

我请求有人指导我。数据框是一个小样本,但我有一个具有类似结构的巨大的样本。

1 个答案:

答案 0 :(得分:1)

只要每个合适的列中至少有1个,就可以使用以下方法。它是确定性的,所以总是只找到第一个并将其与对角线位置的数字交换。但没有组合爆炸。也许有人可以找到更优雅(或矢量化)的解决方案???

fn<- function(colm){
  i1<-match(1, colm)
  colm[i1]<- colm[i]
  colm[i]<-1
  return(colm)
}


for(i in 1:nrow(DF))
{
  DF[,i]=fn(DF[,i])

}

编辑

虽然这个答案在重读时被接受(所以我不能删除),但我认为它并不是你所要求的......

下面的代码应该解决这个问题..

DF<-read.table(text="A    B   C   D
13   0   0   1
1    0   1   10   
0    2   1   15
1    1   0   11", header=T)

rem<-1:nrow(DF)


for(i in 1:nrow(DF))
{
  temp<-DF[i,]
  any1<-intersect(rem, which(DF[,i]==1))
  best1<-which.min(rowSums(DF[any1,]==1))
  firsti<-any1[best1]
  DF[i,]<-DF[firsti,]
  DF[firsti,]<-temp
  rem<-setdiff(rem, i)

}
DF
   A B C  D
1  1 0 1 10
2  1 1 0 11
3  0 2 1 15
4 13 0 0  1

我为混乱道歉。