sto lottando per ottenere i seguenti fatto:estratto voce più recente, in una certa condizione
Esempio set di dati:
belongID uniqID Time Rating
1 101 5 0
1 102 4 0
2 103 4 0
2 104 3 0
2 105 2 5
3 106 4 2
3 107 5 0
3 108 5 1
Il problema è: vorrei estrarre la voce più recente (valore più grande per il tempo) per appartenente, a meno che questa valutazione sia 0. Se la valutazione della voce più recente è 0, tuttavia. Voglio la prima voce con una valutazione (non la valutazione più alta, solo il primo valore con una valutazione diversa da zero). Se anche tutte le altre voci sono zero, è necessario selezionare quello più recente.
Il risultato finale dovrebbe essere di:
belongID uniqID Time Rating
1 101 5 0
2 105 2 5
3 108 5 1
Il set di dati è abbastanza grande ed è ordinato da belongID. Non è ordinato in base all'ora, quindi le voci più recenti possono arrivare dopo le voci più vecchie con lo stesso appartenente.
Senza avere il vincolo "0 Rating", ho usato la seguente funzione per calcolare la voce più recente:
>uniqueMax <- function(m, belongID = 1, time = 3) {
t(
vapply(
split(1:nrow(m), m[,belongID]),
function(i, x, time) x[i, , drop=FALSE][which.max(x[i,time]),], m[1,], x=m, time=time
)
)
}
Non so come incorporare il vincolo "0 Rating".
EDIT: Un follow-up domanda:
Qualcuno sa come la funzione getRating
deve essere modificato se non solo zero rating, ma altre valutazioni devono essere prese in considerazione (per esempio 0,1,4 e 5)? Assegnare così al più recente, a meno che non sia Rating 0 o 1 o 4 o 5? Se il punteggio è 0,1,4,5, assegnare alla voce più recente con una valutazione diversa. Se tutte le valutazioni sono 0,1,4 o 5, assegnale alla più recente di quelle. Ho provato quanto segue, ma che non ha funzionato:
getRating <- function(x){
iszero <- x$Rating == 0 | x$Rating == 1 | x$Rating == 4 | x$Rating ==5
if(all(iszero)){
id <- which.max(x$Time)
} else {
id <- which.max((!iszero)*x$Time)
# This trick guarantees taking 0 into account
}
x[id,]
}
# Do this over the complete data frame
do.call(rbind,lapply(split(Data,Data$belongID),getRating))
# edited per Tyler's suggestion'
appena visto questa risposta, bel +1. Dovrebbe essere più veloce della risposta accettata che avrei pensato. Btw, invece di 'data [order (-Time)] [1]', 'data [order (-Time) [1]]' dovrebbe essere molto più veloce. Il primo modo riordina tutte le colonne, quindi prende la prima riga di quella. Il 2o modo trova la riga necessaria e la prende solo. Maggiore è il numero di colonne, più veloce dovrebbe essere la seconda. –