0

我有以下类型的数据框

   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,])} })

我无法获得所需的输出。
(上述代码的链接-以特定方式排列数据框

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

4

1 回答 1

1

只要每个合适的列中至少有一个 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

我为混乱道歉。

于 2018-03-02T10:52:17.957 回答