R - 将数据框列中的值与另一个数据帧行名称

时间:2016-12-09 19:44:57

标签: r data-manipulation

我认为这在R中是一个相当具有挑战性的数据操作问题,并且很难构建一个能够实现这一目标的函数。背景是组织篮球运动员,他们在不同的位置上一起进入阵容,取决于每个球员的位置。为清楚起见,这里是我正在使用的数据帧的一个示例,有两种不同的形式:

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个位置(PG,SG,PF,SF,C)设置1个球员,我们还需要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

当然,这有一定的灵活性(凯文杜兰特和马基夫莫里斯本可以转换,事实上有几个球员可以在第二个数据帧中切换位置)。我希望能够以相当快的速度将my_df组织成第二种数据帧格式,从my_df获取Pos1和Pos2列,能够检查第二个数据帧的rownames,然后填写播放器名称。

然而,这有一个难题。值得注意的是,并非所有玩家都有第二个位置,但那些拥有第二个位置的玩家可以在两个位置中列出。 (例如,Jimmy Butler可以设置为SG,SF,备用G,备用F或第8人,而Pau Gasol只能设置为C或第8人)。此外,虽然C.J. McCollum被列为PG和SG,但他是my_df中唯一被列为PG的玩家,因此必须进入第二个数据帧的PG行。

任何想法都赞赏这个!如果需要,我可以提供更多背景信息。

(编辑:可能编辑my_df,添加Pos3,Pos4,Pos5列以了解玩家是否可以作为备份G,备份F或第8人,也可以提供帮助,这是我目前正在使用的内容)。< / p>

编辑 - 请参阅Simplify this grid such that each row and column has 1 value了解我的问题的修订版本,这是一个更简单的问题需要解决,但会为我提供这个问题的解决方案!

1 个答案:

答案 0 :(得分:0)

如果有结果,这种方法可以保证返回结果,实际上它将返回所有可行的组合。

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. 使用my_df2
  2. 制作矩阵
  3. 查找所有可能的矩阵替换
  4. 迭代所有可能的矩阵,测试诊断是否全部为1
  5. 选择那些有效的矩阵
  6. 要使输出看起来像您的示例,您可以运行

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