我有以下类型的数据框
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)
我请求有人指导我。数据框是一个小样本,但我有一个具有类似结构的巨大的样本。
答案 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
我为混乱道歉。