R:当两支球队从赛程中与每场比赛3名参赛者互动时,矩阵计数匹配

时间:2016-03-19 11:49:33

标签: r algorithm matrix

我想对FIRST机器人团队进行一些计算,并且由于缺乏更好的词汇,需要构建二元交互矩阵。那是两支球队在同一个联盟的时候。每个联盟有三个团队,因此当考虑(i,j),(j,i)和(i,i)时,每个匹配中有7个值被添加到矩阵中。

我正在使用的完整数据位于:http://frc-events.firstinspires.org/2016/MOKC/qualifications

但为了简单起见,以下是9支球队各1场比赛的例子。

> data.frame(Team.1=1:3,Team.2=4:6,Team.3=7:9)
  Team.1 Team.2 Team.3
1      1      4      7
2      2      5      8
3      3      6      9

矩阵应计算每个二元相互作用,(1,4),(4,7),(3,6),(6,3),(9,9)等,并且将是N×N矩阵,其中在上例中N = 9。这是代表上述列表的矩阵:

> matrix(data=c(1,0,0,1,0,0,1,0,0,+
+ 0,1,0,0,1,0,0,1,0,+
+ 0,0,1,0,0,1,0,0,1,+
+ 1,0,0,1,0,0,1,0,0,+
+ 0,1,0,0,1,0,0,1,0,+
+ 0,0,1,0,0,1,0,0,1,+
+ 1,0,0,1,0,0,1,0,0,+
+ 0,1,0,0,1,0,0,1,0,+
+ 0,0,1,0,0,1,0,0,1),9,9)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    1    0    0    1    0    0    1    0    0
 [2,]    0    1    0    0    1    0    0    1    0
 [3,]    0    0    1    0    0    1    0    0    1
 [4,]    1    0    0    1    0    0    1    0    0
 [5,]    0    1    0    0    1    0    0    1    0
 [6,]    0    0    1    0    0    1    0    0    1
 [7,]    1    0    0    1    0    0    1    0    0
 [8,]    0    1    0    0    1    0    0    1    0
 [9,]    0    0    1    0    0    1    0    0    1

在实际数据中,团队编号不是连续的,并且更像是5732,1345,3451等,并且每个团队有更多匹配,这意味着矩阵值将介于0和最大匹配数之间球队的比赛。这可以在真实数据中看到。

感谢任何可以提供帮助的人。

2 个答案:

答案 0 :(得分:2)

可能有更优雅的方法,但这里有一个使用data.table。

library(data.table)
dat <- data.table(Team.1=1:3,Team.2=4:6,Team.3=7:9)

#add match ID
dat[,match:=1:.N]
#turn to long
mdat <- melt(dat,id="match",value.name="team")[,variable:=NULL]

#merge with itself
dat2 <- merge(mdat, mdat, by=c("match"),all=T, allow.cartesian = T)

# reshape
dcast(dat2, team.x~team.y, fun.agg=length)

   team.x 1 2 3 4 5 6 7 8 9
1:      1 1 0 0 1 0 0 1 0 0
2:      2 0 1 0 0 1 0 0 1 0
3:      3 0 0 1 0 0 1 0 0 1
4:      4 1 0 0 1 0 0 1 0 0
5:      5 0 1 0 0 1 0 0 1 0
6:      6 0 0 1 0 0 1 0 0 1
7:      7 1 0 0 1 0 0 1 0 0
8:      8 0 1 0 0 1 0 0 1 0
9:      9 0 0 1 0 0 1 0 0 1

而且,因为我可以,一个在基地R。我认为使用for循环的情况是合理的(因为你不断修改同一个对象)。

#make matrix to put results in

nteams = length(unique(unlist(dat)))
res <- matrix(0,nrow=nteams, ncol=nteams)


#split data by row, generate combinations for each row and add to matrix
for(i in 1:nrow(dat)){
  x=unlist(dat[i,])
  coords=as.matrix(expand.grid(x,x))
  res[coords] <- res[coords]+1
}

答案 1 :(得分:2)

这是我对基本功能的建议。我试图创建一个矩阵。我的方法是寻找1的位置索引。

library(magrittr)

mydf <- data.frame(Team.1 = 1:3, Team.2 = 4:6,Team.3 = 7:9)

### Create a matrix with position indexes

lapply(1:nrow(mydf), function(x){

       a <- t(combn(mydf[x, ], 2)) # Get some combination
       b <- a[, 2:1] # Get other combination by reversing columns
       foo <- rbind(a, b)
       foo

     }) %>%
do.call(rbind, .) -> ana

ana <- matrix(unlist(ana), nrow = nrow(ana))


### Another set: Get indexes for self (e.g., (1,1), (2,2), (3,3))

foo <- rep(1:max(mydf), times = 2)
matrix(foo, nrow = length(foo) / 2) -> bob


### A matric with all position indexes
cammy <- rbind(ana, bob)


### Create a plain matrix
mat <- matrix(0, nrow = max(mydf), ncol = max(mydf))

### Fill in the matrix with 1
mat[cammy] <- 1

#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
# [1,]    1    0    0    1    0    0    1    0    0
# [2,]    0    1    0    0    1    0    0    1    0
# [3,]    0    0    1    0    0    1    0    0    1
# [4,]    1    0    0    1    0    0    1    0    0
# [5,]    0    1    0    0    1    0    0    1    0
# [6,]    0    0    1    0    0    1    0    0    1
# [7,]    1    0    0    1    0    0    1    0    0
# [8,]    0    1    0    0    1    0    0    1    0
# [9,]    0    0    1    0    0    1    0    0    1

修改

这是基于之前想法的修订版。这并不像Heroka的基本功能一样简洁。在我修改过的数据中,第1队和第4队有两场比赛。这里的想法是我计算每对出现在数据集中的次数。 dplyr部分正在这样做。在for循环中,我通过遍历cammy的每一行填充矩阵,mat。

mydf <- data.frame(Team.1=c(1:3,1),Team.2=c(4:6,4),Team.3=c(7:9,5))


#  Team.1 Team.2 Team.3
#1      1      4      7
#2      2      5      8
#3      3      6      9
#4      1      4      5

library(dplyr)

lapply(1:nrow(mydf), function(x){

       a <- t(combn(mydf[x, ], 2)) # Get some combination
       b <- a[, 2:1] # Get other combination by reversing columns
       foo <- rbind(a, b)
       foo

     }) %>%
do.call(rbind, .) -> ana

ana <- data.frame(matrix(unlist(ana), nrow = nrow(ana)))


### Another set: Get indexes for self (e.g., (1,1), (2,2), (3,3))
foo <- rep(1:max(mydf), times = 2)
data.frame(matrix(foo, nrow = length(foo) / 2)) -> bob


cammy <- bind_rows(ana, bob) %>%
         group_by(X1, X2) %>%
         mutate(total = n()) %>%
         as.matrix


### Create a plain matrix
mat <- matrix(0, nrow = max(mydf), ncol = max(mydf))



for(i in 1:nrow(cammy)){

    mat[cammy[i, 1], cammy[i, 2]] <- cammy[i, 3]
}

print(mat)

#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
# [1,]    1    0    0    2    1    0    1    0    0
# [2,]    0    1    0    0    1    0    0    1    0
# [3,]    0    0    1    0    0    1    0    0    1
# [4,]    2    0    0    1    1    0    1    0    0
# [5,]    1    1    0    1    1    0    0    1    0
# [6,]    0    0    1    0    0    1    0    0    1
# [7,]    1    0    0    1    0    0    1    0    0
# [8,]    0    1    0    0    1    0    0    1    0
# [9,]    0    0    1    0    0    1    0    0    1