2016-12-09 38 views
0

これはRのかなり困難なデータ操作の問題だと思うし、これを実現する関数の構築には苦労している。コンテキストは、各プレイヤーがどのポジションをプレイしているかに応じて、異なるポジションをラインナップして一緒にプレイするバスケットボール選手を編成することです。いくつか明確にするために、ここで私は2つの異なる形で、で働いていますデータフレームの例である:データフレーム列の値を別のデータフレームの行の名前に一致させる

dput(my_df) 
structure(list(Name = c("C.J. McCollum", "DeMar DeRozan", "Jimmy Butler", 
"Jonas Valanciunas", "Kevin Durant", "Markieff Morris", "Pascal Siakam", 
"Pau Gasol"), Pos1 = c("PG", "SG", "SG", "C", "SF", "SF", "PF", 
"C"), Pos2 = c("SG", "", "SF", "", "PF", "PF", "", "")), .Names = c("Name", 
"Pos1", "Pos2"), class = "data.frame", row.names = c(18L, 33L, 
62L, 68L, 78L, 92L, 106L, 111L)) 

my_df 
       Name Pos1 Pos2 
18  C.J. McCollum PG SG 
33  DeMar DeRozan SG  
62  Jimmy Butler SG SF 
68 Jonas Valanciunas C  
78  Kevin Durant SF PF 
92 Markieff Morris SF PF 
106  Pascal Siakam PF  
111   Pau Gasol C  


dput(my_df2) 
structure(list(Name = c("C.J. McCollum", "DeMar DeRozan", "Jimmy Butler", 
"Jonas Valanciunas", "Kevin Durant", "Markieff Morris", "Pascal Siakam", 
"Pau Gasol"), Pos1 = c("PG", "SG", "SG", "C", "SF", "SF", "PF", 
"C"), Pos2 = c("SG", "", "SF", "", "PF", "PF", "", ""), PG = c(1, 
0, 0, 0, 0, 0, 0, 0), SG = c(1, 1, 1, 0, 0, 0, 0, 0), SF = c(0, 
0, 1, 0, 1, 1, 0, 0), PF = c(0, 0, 0, 0, 1, 1, 1, 0), C = c(0, 
0, 0, 1, 0, 0, 0, 1), BackupG = c(1, 1, 1, 0, 0, 0, 0, 0), BackupF = c(0, 
0, 1, 0, 1, 1, 1, 0), Man8 = c(1, 1, 1, 1, 1, 1, 1, 1)), .Names = c("Name", 
"Pos1", "Pos2", "PG", "SG", "SF", "PF", "C", "BackupG", "BackupF", 
"Man8"), row.names = c(18L, 33L, 62L, 68L, 78L, 92L, 106L, 111L 
), class = "data.frame") 


my_df2 
       Name Pos1 Pos2 PG SG SF PF C BackupG BackupF Man8 
18  C.J. McCollum PG SG 1 1 0 0 0  1  0 1 
33  DeMar DeRozan SG  0 1 0 0 0  1  0 1 
62  Jimmy Butler SG SF 0 1 1 0 0  1  1 1 
68 Jonas Valanciunas C  0 0 0 0 1  0  0 1 
78  Kevin Durant SF PF 0 0 1 1 0  0  1 1 
92 Markieff Morris SF PF 0 0 1 1 0  0  1 1 
106  Pascal Siakam PF  0 0 0 1 0  0  1 1 
111   Pau Gasol C  0 0 0 0 1  0  0 1 

バスケットボールのラインナップでは、我々はバスケットボールで5位のそれぞれについて、1人のプレーヤーのセットをしたい(PG、SG 、PF、SF、C)、1つのバックアップガード(PGまたはSGはガード)、1つのバックアップフォワード(PFまたはFSはフォワード)、および任意の位置をプレイできる8番目のプレイヤーが必要です。 8人の選手のこのグループでは、我々はこのようにラインアップを構築することができます:

     Name 
     PG C.J. McCollum 
     SG DeMar DeRozan 
     PF Kevin Durant 
     SF Markieff Morris 
      C Pau Gasol 
    Backup G Jimmy Butler 
    Backup F Pascal Siakam 
    8th Man Jonas Valanciunas 

は勿論これにある程度の柔軟性があります(ケビン・デュラントとマーキーフ・モリスが実際に切り替わっている可能性がいくつかの選手をtheresの、切り替えされている可能性が第2のデータフレームのスポット)。私はmy_dfからPos1とPos2の列を取り、2番目のデータフレームのrownamesをチェックし、次にプレイヤー名を記入することができるかなり簡単な問題で、この2番目のデータフレーム形式にmy_dfを編成できるようにしたいと思います。

しかし、これにはパズルの側面があります。注目すべきは、すべての選手が2位を持っているわけではないが、2位の選手を2つのポジションのいずれかに挙げることができるということである。 (例えば、ジミーバトラーは、SG、SF、バックアップG、バックアップF、または第8人に設定できますが、ポーガソルはCまたは8人としてのみ設定できます)。さらに、C.J. McCollumはPGとSGとしてリストされていますが、my_dfではPGとしてリストされている唯一のプレイヤーであるため、2番目のデータフレームのPG行に移動する必要があります。

これに感謝しています。必要に応じてより多くの文脈を提供することができます。

(編集:潜在的にmy_dfを編集して、プレイヤーがバックアップG、バックアップF、または8番目の男になるかどうかをPos3、Pos4、Pos5の列を追加すると、現在役立っているかもしれません)。

編集 - 私の質問の改訂版はSimplify this grid such that each row and column has 1 valueを参照してください。これは解決するのはより簡単な問題ですが、私にはこの問題の解決策が与えられます!

答えて

0

このアプローチは、結果が1つのみであれば結果を返すことが保証されていますが、実際にはすべての実行可能な組み合わせが返されます。

st<-as.matrix(my_df2[4:dim(my_df2)[2]]) # Make a numeric matrix 

## allCombinationsAux may not be necessary if you are using a combinatorics library 
allCombinationsAux<-function(z,nreg,x){ 
    if(sum(nreg)>1){ 
     innerLoop<-do.call(rbind,lapply(x[nreg&(z!=x)], test1,nreg&(z!=x),x)) 
     ret<-cbind(z,innerLoop) 
    } 
    else{ 
     ret<-x[nreg] 
    } 
    ret 
} 

## Find all the possible row combinations for the matrix 
combs<-do.call(rbind,lapply(x,function(y) allCombinationsAux(y,y!=x,x))) 

## Identify which combinations are valid 
inds<-which(apply(combs,1,function(x) sum(diag(st[x,]))==8)) 

## Select valid matricies 
validChoices<-lapply(inds,function(x) st[combs[x,],]) 
  1. 有効であるこれらの行列を選択ダイアグはすべて1
  2. をしている場合は、すべての可能な行列のテストを介してすべての可能な行列の置換
  3. 反復を探すmy_df2
  4. のうち行列を作る

あなたの例のように出力を得るには、実行することができます

validChoices<-lapply(inds,function(x) { 
    matr<-st[combs[x,],] 
    retVal<-data.frame(Name=my_df2[combs[x,],"Name"]) 
    rownames(retVal)<-colnames(matr) 
    retVal 
    }) 
関連する問題