2012-09-12 17 views
9

Ho bisogno di ottenere la media di una colonna (qui: punteggio) per righe specifiche (qui: anni). In particolare, vorrei sapere il punteggio medio per tre periodi:Come ottenere la media della colonna solo per le righe specifiche?

  • periodo 1: anno < = 1983
  • periodo di 2: anni> = 1984 & anno < = 1990
  • periodo di 3: anno> = 1991

Questa è la struttura dei miei dati:

country year  score   
Algeria 1980  -1.1201501 
Algeria 1981  -1.0526943 
Algeria 1982  -1.0561565 
Algeria 1983  -1.1274560 
Algeria 1984  -1.1353926 
Algeria 1985  -1.1734330 
Algeria 1986  -1.1327666 
Algeria 1987  -1.1263586 
Algeria 1988  -0.8529455 
Algeria 1989  -0.2930265 
Algeria 1990  -0.1564207 
Algeria 1991  -0.1526328 
Algeria 1992  -0.9757842 
Algeria 1993  -0.9714060 
Algeria 1994  -1.1422258 
Algeria 1995  -0.3675797 
... 

I valori medi calcolati devono essere aggiunti al df in una colonna aggiuntiva ("media"), vale a dire lo stesso valore medio per anni del periodo 1, per quelli del periodo 2, ecc.

Ecco come dovrebbe essere:

country year  score   mean 
Algeria 1980  -1.1201501  -1.089 
Algeria 1981  -1.0526943  -1.089 
Algeria 1982  -1.0561565  -1.089 
Algeria 1983  -1.1274560  -1.089 
Algeria 1984  -1.1353926  -0.839 
Algeria 1985  -1.1734330  -0.839 
Algeria 1986  -1.1327666  -0.839 
Algeria 1987  -1.1263586  -0.839 
Algeria 1988  -0.8529455  -0.839 
Algeria 1989  -0.2930265  -0.839 
Algeria 1990  -0.1564207  -0.839 
... 

ogni possibile percorso ho provato ottenuto facilmente super-complicato - e devo calcolare i punteggi medi per i diversi periodi di tempo per più di 90 paesi ...

molte grazie per il vostro aiuto!

risposta

14
datfrm$mean <- 
    with (datfrm, ave(score, findInterval(year, c(-Inf, 1984, 1991, Inf)), FUN= mean)) 

La domanda del titolo è un po 'diversa dalla vera domanda e si otterrebbe una risposta utilizzando l'indicizzazione logica. Se si volesse solo la media per un particolare sottoinsieme dire year >= 1984 & year <= 1990 sarebbe stato fatto attraverso:

mn84_90 <- with(datfrm, mean(score[year >= 1984 & year <= 1990])) 
+0

WOW! Questo è stato incredibilmente veloce e davvero molto utile. Grazie mille per questa soluzione super elegante! – TiF

+4

La funzione 'findInterval' ha bisogno di un'agenzia pubblicitaria migliore. –

5

Dal findInterval richiede year da ordinare (come è nel tuo esempio) sarei tentato di utilizzare cut in caso non è risolto [si è rivelato sbagliato, grazie @DWin]. Per completezza le data.table equivalenti (scale per dati di grandi dimensioni) è:

require(data.table) 
DT = as.data.table(DF) # or just start with a data.table in the first place 

DT[, mean:=mean(score), by=cut(year,c(-Inf,1984,1991,Inf))] 

o findInterval rischia più veloce come quello usato DWin:

DT[, mean:=mean(score), by=findInterval(year,c(-Inf,1984,1991,Inf))] 
+2

Questa indicazione su findInterval non è corretta (confermata dopo il test), ma grazie per l'offerta di DT. –

+0

Grazie per averlo provato !! – TiF

+1

@DWin. Mi scuso, ho confuso 'vec' e' x'. Hai ragione. –

Problemi correlati