2016-03-19 5 views
1

Ich möchte einige Berechnungen an FIRST Robotics Teams vornehmen und muss aus Mangel an besseren Worten eine binäre Interaktionsmatrix erstellen. Damals waren zwei Teams in derselben Allianz. Jede Allianz hat drei Teams, also gibt es 7 Werte von jeder Übereinstimmung, die zu der Matrix hinzugefügt werden, wenn (i, j), (j, i) und (i, i) berücksichtigt werden.R: Matrix-Zähltreffer, wenn 2 Teams mit 3 Teilnehmern pro Spiel interagierten

Die vollständige Daten Ich verwende hier: http://frc-events.firstinspires.org/2016/MOKC/qualifications

Aber der Einfachheit halber hier ein Beispiel von 9 Teams spielen 1 Spiel pro Person.

> 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 

Die Matrix jede binäre Wechselwirkung zählen, (1,4), (4,7), (3,6), (6,3), (9,9), etc., und wird eine N × N-Matrix, wobei im obigen Beispiel N = 9 ist. Hier ist die Matrix, die die oben genannten Listen darstellt:

> 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 

In den realen Daten, ist die Teamnummer nicht sequenziell, und ist wäre eher wie 5732,1345,3451, etc., und es gibt mehr Spiele pro Mannschaft Bedeutung Die Matrixwerte würden zwischen 0 und der maximalen Anzahl von Spielen eines der gespielten Teams liegen. Dies kann in den realen Daten gesehen werden.

Dank an alle, die helfen können.

+0

Könnten Sie vielleicht näher erläutern, was die Zeilen und Spalten Ihrer Matrix bedeuten? Ich interpretiere, wie "Team 1 Team 4 und 7 einmal getroffen hat". Ist das korrekt? – Heroka

+0

Das ist richtig. Aus dem Spielplan waren 1,4 und 7 zusammen, und so addiert man eins zu (1,1), (1,4), (4,7), (1,7), (4,1), (7,4) und (7,1) in der Matrix, wo Sie haben (Zeile, Spalte). – ngreen08

Antwort

2

Es gibt wahrscheinlich einen eleganteren Ansatz, aber hier ist einer mit 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 

Und weil ich kann, einer in der Basis-R. Ein Fall, in dem ich denke, dass die Verwendung einer For-Schleife gerechtfertigt ist (weil Sie das gleiche Objekt weiter modifizieren).

#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 
} 
+0

[Vor langer Zeit] (http://news.mrdwab.com/post/elegant/) ... :-) – A5C1D2H2I1M1N2O1R2T1

2

Hier ist mein Vorschlag mit Basisfunktionen. Ich habe versucht, eine Matrix zu erstellen. Mein Ansatz war für die Positionsindizes suchen 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 

EDIT

Hier ist eine überarbeitete Version auf der vorherigen Idee basiert. Dies ist nicht prägnant wie Herokas Idee mit Basisfunktionen. In meinen modifizierten Daten hatten Team 1 und 4 zwei Matches. Die Idee hier ist, dass ich gezählt habe, wie oft jedes Paar im Datensatz erschien. Der dplyr Teil macht das. In der for-Schleife füllte ich die Matrix durch jede Zeile von cammy.

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 
+0

Schön. Aber wie würde das funktionieren, wenn ein Team mehrmals erscheint? (Wie in OP Beschreibung) – Heroka

+0

@Heroka Danke für Ihren Kommentar. Ich muss über diesen Punkt nachdenken. – jazzurro

+1

@Heroka Ich habe getan, was ich tun konnte. Meine Idee ist nicht prägnant wie deine. Aber ich habe versucht, meine ursprüngliche Idee zu nutzen und mehr hinzugefügt, um das Problem anzugehen. Hier Zeit, jetzt ins Bett zu gehen. Wenn Sie mir einen Rat geben können, um meine Idee zu verbessern, würde mir das helfen. – jazzurro