2015-05-11 15 views
13

Ho un set di dati dei risultati delle partite di calcio, e spero di imparare R creando un set di rating in corso simile alla formula World Football Elo. Sono in esecuzione nei guai con le cose che sembrano essere semplice in Excel non sono esattamente intuitivo in R. Per esempio, il primo 15 di 4270 osservazioni con le variabili necessarie:Creazione di una variabile di conteggio in esecuzione in R?

 date t.1 t.2 m.result 
1 19960406 DC SJ  0.0 
2 19960413 COL KC  0.0 
3 19960413 NE TB  0.0 
4 19960413 CLB DC  1.0 
5 19960413 LAG NYRB  1.0 
6 19960414 FCD SJ  0.5 
7 19960418 FCD KC  1.0 
8 19960420 NE NYRB  1.0 
9 19960420 DC LAG  0.0 
10 19960420 CLB TB  0.0 
11 19960421 COL FCD  1.0 
12 19960421 SJ KC  0.5 
13 19960427 CLB NYRB  1.0 
14 19960427 DC NE  0.5 
15 19960428 FCD TB  1.0 

Voglio essere in grado di creare una nuova variabile che sarà un conteggio delle partite totali giocate da t.1 e t.2 giocate (cioè le istanze fino alla data in questione che "DC" si verifica nelle colonne t.1 o t.2):

  date t.1 t.2 m.result ##t.1m ##t.2m 
    1 19960406 DC SJ  0.0  1   1 
    2 19960413 COL KC  0.0  1   1 
    3 19960413 NE TB  0.0  1   1 
    4 19960413 CLB DC  1.0  1   2 
    5 19960413 LAG NYRB  1.0  1   1 
    6 19960414 FCD SJ  0.5  1   2 
    7 19960418 FCD KC  1.0  2   2 
    8 19960420 NE NYRB  1.0  2   2 
    9 19960420 DC LAG  0.0  3   2 
    10 19960420 CLB TB  0.0  2   2 
    11 19960421 COL FCD  1.0  2   3 
    12 19960421 SJ KC  0.5  3   3 
    13 19960427 CLB NYRB  1.0  3   3 
    14 19960427 DC NE  0.5  4   3 
    15 19960428 FCD TB  1.0  4   3 

in Excel, questo è un (relativamente) semplice equazione = SUMPRODUCT, ad esempio:

E4=SUMPRODUCT((A:A<=A4)*(B:B=B4))+SUMPRODUCT((A:A<=A4)*(C:C=B4)) 

dove E4 è t.1m per oss # 4, A: A è data, B: B è t.1, C: C è T.2, ecc

Ma in R, posso ottenere totale sumproduct stampato per me (es "DC" ha giocato 576 giochi attraverso il mio set di dati), ma per qualche ragione (probabilmente sono nuovo, impaziente, sbalordito da prove ed errori) mi sono perso su come fare un conteggio in esecuzione sui dati di osservazione, e specialmente come rendere quel conteggio progressivo in una variabile, che è vitale per qualsiasi indice di valutazione del gioco. So che "PlayerRatings" esiste, credo che per la mia educazione R dovrei essere in grado di farlo nella suite R senza quel pacchetto. plyr o dplyr va bene, certo.

Per riferimento, ecco i miei dati per copiare/incollare nel vostro R.

date<-c(19960406,19960413,19960413,19960413,19960413,19960414,19960418,19960420,19960420,19960420,19960421,19960421,19960427,19960427,19960428) 
t.1<-c("DC","COL","NE","CLB","LAG","FCD","FCD","NE","DC","CLB","COL","SJ","CLB","DC","FCD") 
t.2<-c("SJ","KC","TB","DC","NYRB","SJ","KC","NYRB","LAG","TB","FCD","KC","NYRB","NE","TB") 
m.result<-c(0.0,0.0,0.0,1.0,1.0,0.5,1.0,1.0,0.0,0.0,1.0,0.5,1.0,0.5,1.0) 
mtable<-data.frame(date,t.1,t.2,m.result) 
mtable 
+0

correlati: [conteggio parziale in base al campo in R] (http://stackoverflow.com/q/31259932/452096) . Quella diede risposte che funzionavano molto più velocemente sul mio grosso problema rispetto alla risposta accettata sotto. –

risposta

4

Ecco una soluzione molto semplice che non è bella, ma non il lavoro.

In primo luogo, solo un cambiamento ai dati per effettuare confronti più facili:

mtable<-data.frame(date,t.1,t.2,m.result, stringsAsFactors = FALSE) 

modificato in:

Se si vuole assicurare le partite sono ordinate per data, è possibile utilizzare order come indicato da @ eipi10:

mtable = mtable[order(mtable$date), ] 

Tieni presente che, nel caso in cui le date siano in un formato che l'ordine cronologico non è l'ordine intero, puoi prima convertirle in formato Data utilizzando as.Date().


Quello che faremo è, per ogni riga, prendere un sottoinsieme del dataframe con le colonne t.1 e t.2, con tutte le righe da 1 a detta fila. Quindi 1: 1, 1: 2, 1: 3, ecc. Ad ogni corsa, contiamo il numero di volte che la squadra è apparsa e la usiamo come risultato per la nuova colonna.

mtable$t.1m <- sapply(1:nrow(mtable), 
      function(i) sum(mtable[1:i, c("t.1", "t.2")] == mtable$t.1[i])) 

Questo è stato fatto per le squadre in t.1, con un piccolo cambiamento su argomento dopo == possiamo fare per t.2:

mtable$t.2m <- sapply(1:nrow(mtable), 
      function(i) sum(mtable[1:i, c("t.1", "t.2")] == mtable$t.2[i])) 

Ora il nostro dataframe assomiglia a questo:

> mtable 
     date t.1 t.2 m.result t.1m t.2m 
1 19960406 DC SJ  0.0 1 1 
2 19960413 COL KC  0.0 1 1 
3 19960413 NE TB  0.0 1 1 
4 19960413 CLB DC  1.0 1 2 
5 19960413 LAG NYRB  1.0 1 1 
6 19960414 FCD SJ  0.5 1 2 
7 19960418 FCD KC  1.0 2 2 
8 19960420 NE NYRB  1.0 2 2 
9 19960420 DC LAG  0.0 3 2 
10 19960420 CLB TB  0.0 2 2 
11 19960421 COL FCD  1.0 2 3 
12 19960421 SJ KC  0.5 3 3 
13 19960427 CLB NYRB  1.0 3 3 
14 19960427 DC NE  0.5 4 3 
15 19960428 FCD TB  1.0 4 3 
+0

Grazie! Funziona bene Follow-up: Ho notato che non ti riferisci affatto alla variabile data. Supponiamo che i miei dati fossero sparsi su variabili di date e voglio ordinare il mio conteggio di corsa nel più breve tempo in cui una squadra ha giocato una partita. Il codice cambia del tutto? –

+1

Puoi ordinare la tabella per data prima di eseguire il codice di Molx: 'mtable = mtable [ordine (mtable $ date),]'. – eipi10

5

Nel passaggio di creazione dei dati, assicurati che stringsAsFactors = FALSE eviti i problemi. Quindi è facile da fare. (Edit: Ho fatto questo un all dplyr esempio)

library(dplyr) 

cross_count <- function(id, var) { 
    length(which(mtable[id, var] == mtable[1:id, ] %>% select(t.1, t.2) %>% unlist)) 
} 

mtable %>% 
    arrange(date) %>% # This makes sure the dates are in order 
    mutate(id = 1:nrow(.)) %>% 
    rowwise() %>% 
    mutate(t.1m = cross_count(id, 2), t.2m = cross_count(id, 3)) 




date t.1 t.2 m.result id t.1m t.2m 
1 19960406 DC SJ  0.0 1 1 1 
2 19960413 COL KC  0.0 2 1 1 
3 19960413 NE TB  0.0 3 1 1 
4 19960413 CLB DC  1.0 4 1 2 
5 19960413 LAG NYRB  1.0 5 1 1 
6 19960414 FCD SJ  0.5 6 1 2 
7 19960418 FCD KC  1.0 7 2 2 
8 19960420 NE NYRB  1.0 8 2 2 
9 19960420 DC LAG  0.0 9 3 2 
10 19960420 CLB TB  0.0 10 2 2 
11 19960421 COL FCD  1.0 11 2 3 
12 19960421 SJ KC  0.5 12 3 3 
13 19960427 CLB NYRB  1.0 13 3 3 
14 19960427 DC NE  0.5 14 4 3 
15 19960428 FCD TB  1.0 15 4 3 
-1

per raggiungere questo obiettivo usando un modo simile come lei ha ricordato:

sum(mtable$t.1 == 'DC', mtable$t.2 == 'DC') 
+0

E il risultato è: 4 –

0

Sembra che le colonne separate t.1m e t.2m sono per la contabilità, e sei davvero interessato al numero di partite giocate? Ho usato with() per lavorare con le colonne della mtable senza dover scrivere mtable ogni volta

mtable$games <- with(mtable, { 

Se una squadra particolare gioca, gioca sia come squadra 1 o squadra 2

played <- t.1 == "DC" | t.2 == "DC" 

Il confronto è vettorializzare confrontando ogni elemento della colonna t.1 con "DC", ecc. e il confronto logico viene anche vettorizzato in modo tale da ottenere un singolo |.

Una parte difficile dei dati è che diverse squadre giocano in un solo giorno, e il giorno della partita (a quanto pare) solo il team centrale dovrebbe essere incrementato. Ho sistemato questo capire come ordinare i giochi in modo che la squadra focale è sempre ultimo in ordine il giorno in cui ha giocato

o <- order(date, played) 

poi calcolata la somma cumulativa di partite giocate

games <- cumsum(played[o]) 

e mettere i giochi di nuovo nel loro ordine originale

games[order(o)] 
}) 

Ecco il risultato

> head(mtable, 11) 
     date t.1 t.2 m.result games 
1 19960406 DC SJ  0.0  1 
2 19960413 COL KC  0.0  1 
3 19960413 NE TB  0.0  1 
4 19960413 CLB DC  1.0  2 
5 19960413 LAG NYRB  1.0  1 
6 19960414 FCD SJ  0.5  2 
7 19960418 FCD KC  1.0  2 
8 19960420 NE NYRB  1.0  2 
9 19960420 DC LAG  0.0  3 
10 19960420 CLB TB  0.0  2 
11 19960421 COL FCD  1.0  3 

Ecco una funzione che implementa questa, che consente un facile specificazione della squadra focale

gamesplayed <- function(date, t1, t2, focal="DC") { 
    played <- t1 == focal | t2 == focal 
    o <- order(date, played) 
    cumsum(played[o])[order(o)] 
} 
Problemi correlati