Bereken de verstreken "tijden", waarbij de referentietijd afhankelijk is van een factor

Ik probeer de verstreken tijd in een dataframe te berekenen, waarbij de 'start'-waarde voor de verstreken tijd afhangt van de waarde van een factorkolom in het dataframe. (Om de vraag simpel te stellen, behandel ik de tijdwaarden als numerieke in plaats van tijdobjecten - mijn vraag gaat over split-apply-combineer, niet over tijdobjecten). Mijn gegevensframe ziet er als volgt uit:

df <- data.frame(id=gl(2, 3, 5, labels=c("a", "b")), time=1:5)

Ik wil de verstreken tijden berekenen door de minimumtijd in elk factor niveau van elke keer af te trekken (hoewel ik omwille van dit voorbeeld alleen numerieke waarden zal behandelen, geen tijdwaarden). Dus ik wil het dataframe splitsen door id , de minimumwaarde y aftrekken van elk element in de kolom y en een vector (of dataframe) met de getransformeerde waarden. Ik wil eindigen met iets als:

> dfTrans
id  time  elapsed
a      1        0
a      2        1
a      3        2
b      4        0
b      5        1   

Het lijkt een perfecte taak voor plyr, maar ik kan geen eenvoudige oplossing vinden.

Het beste wat ik kan bedenken is

elapsed <- dlply(df, .(id), function(x) x$time - min(x$time))
elapsed_comb <- NA
for(i in 1:length(names(elapsed))) {
  elapsed_comb <- c(elapsed_comb, elapsed[[i]])
}
elapsed_comb <- elapsed_comb[-1]
df$elapsed <- elapsed_comb

Dit is onelegant en lijkt fragiel. Er is toch een betere manier?

0

2 antwoord

De functie 'ave' is het eerste waar u aan moet denken als de resultaten een vector moeten zijn met dezelfde lengte als het aantal rijen in het dataframe:

 df$elapsed <- ave(df$time, df$id, FUN=function(x) x -min(x) )
 df
  id time elapsed
1  a    1       0
2  a    2       1
3  a    3       2
4  b    4       0
5  b    5       1
3
toegevoegd

Hier is een Ddply-oplossing

ddply(df, .(id), summarize, time = time, elapsed = seq(length(id))-1)

en een die in plaats daarvan rle gebruikt

df$elapsed <- unlist(sapply(rle(as.numeric(df$id))$lengths, seq))-1
2
toegevoegd
Waarschijnlijk. Dat is niet waar ik meteen aan dacht. Ik heb de hele dag de meettheorie bestudeerd en mijn hoofd werkt niet helemaal goed.
toegevoegd de auteur Dason, de bron
Zou het niet iets natuurlijker zijn om transform te gebruiken: ddply (df,. (Id), transform, elapsed = time - min (time)) ?
toegevoegd de auteur joran, de bron
Ugh. Mijn medeleven. Neem een ​​biertje, dan werken je hersenen weer goed.
toegevoegd de auteur joran, de bron