Próbowałem użyć rozłamu i Tapply nieco więcej, aby stać się bardziej zapoznać się z nimi. Wiem, że to pytanie zostało już odebrane, ale pomyślałem, że dodam jeszcze jedną solodowanie za pomocą podziału (przepraszam za brzydotę, jestem bardziej niż otwarty na informacje zwrotne w celu poprawy, myślę, że być może było zastosowanie do strojenia w celu zmniejszenia kodu):
sdf <-with(df, split(df, ID))
max.week <- sapply(seq_along(sdf), function(x) which.max(sdf[[x]][, 'week']))
data.frame(t(mapply(function(x, y) y[x, ], max.week, sdf)))
Pomyślałem również, dlaczego mamy 7 odpowiedzi tutaj, że dojrzała do punktu odniesienia. Wyniki mogą być zaskakujące (za pomocą rbenchmark z R2.14.1 na Win 7 maszynie):
# library(rbenchmark)
# benchmark(
# DATA.TABLE= {dt <- data.table(df, key="ID")
# dt[, .SD[which.max(outcome),], by=ID]},
# DO.CALL={do.call("rbind",
# by(df, INDICES=df$ID, FUN=function(DF) DF[which.max(DF$week),]))},
# PLYR=ddply(df, .(ID), function(X) X[which.max(X$week), ]),
# SPLIT={sdf <-with(df, split(df, ID))
# max.week <- sapply(seq_along(sdf), function(x) which.max(sdf[[x]][, 'week']))
# data.frame(t(mapply(function(x, y) y[x, ], max.week, sdf)))},
# MATCH.INDEX=df[rev(rownames(df)),][match(unique(df$ID), rev(df$ID)), ],
# AGGREGATE=df[cumsum(aggregate(week ~ ID, df, which.max)$week), ],
# #WHICH.MAX.INDEX=df[sapply(unique(df$ID), function(x) which.max(x==df$ID)), ],
# BRYANS.INDEX = df[cumsum(as.numeric(lapply(split(df$week, df$ID),
# which.max))), ],
# SPLIT2={sdf <-with(df, split(df, ID))
# df[cumsum(sapply(seq_along(sdf), function(x) which.max(sdf[[x]][, 'week']))),
# ]},
# TAPPLY=df[tapply(seq_along(df$ID), df$ID, function(x){tail(x,1)}),],
# columns = c("test", "replications", "elapsed", "relative", "user.self","sys.self"),
# order = "test", replications = 1000, environment = parent.frame())
test replications elapsed relative user.self sys.self
6 AGGREGATE 1000 4.49 7.610169 2.84 0.05
7 BRYANS.INDEX 1000 0.59 1.000000 0.20 0.00
1 DATA.TABLE 1000 20.28 34.372881 11.98 0.00
2 DO.CALL 1000 4.67 7.915254 2.95 0.03
5 MATCH.INDEX 1000 1.07 1.813559 0.51 0.00
3 PLYR 1000 10.61 17.983051 5.07 0.00
4 SPLIT 1000 3.12 5.288136 1.81 0.00
8 SPLIT2 1000 1.56 2.644068 1.28 0.00
9 TAPPLY 1000 1.08 1.830508 0.88 0.00
Edit1: pominąłem które rozwiązanie MAX, ponieważ nie zwraca poprawne wyniki i wrócił agregatu rozwiązanie jako dobrze, że chciałem użyć (komplementy Bryana Goodricha) i zaktualizowanej wersji split, SPLIT2, używając cumsum (podobał mi się ten ruch).
Edycja 2: Dason również włączył rozwiązanie tapply, które rzuciłem w test, który również wypadł całkiem dobrze.
Jak na bok, upewnij się, że robisz coś sensownego z te dane; samo uwzględnienie ostatniej dostępnej oceny może prowadzić do bardzo błędnych wniosków, w zależności od tego, dlaczego brakuje danych i czego szukasz. – Aaron