2015-07-08 8 views
5

Ci scusiamo se è stato chiesto in precedenza, ma non sono riuscito a trovare alcuna domanda che risponda esattamente a questo. Ho un dato come questo:Ottenere i dati (t-1) all'interno dei gruppi

Project  Date price 
     A 30/3/2013 2082 
     B 19/3/2013 1567 
     B 22/2/2013 1642 
     C 12/4/2013 1575 
     C 5/6/2013 1582 

voglio avere una colonna con prezzi dell'ultima istanza per gruppo. Ad esempio, per riga 2, l'ultimo prezzo istanza per lo stesso gruppo sarà 1642. I dati definitivi saranno guardare un po 'come questo:

Project  Date price lastPrice 
     A 30/3/2013 2082   0 
     B 19/3/2013 1567  1642 
     B 22/2/2013 1642   0 
     C 12/4/2013 1575   0 
     C 5/6/2013 1582  1575 

Come fare questo? Il problema principale che sto affrontando è che i dati potrebbero non essere ordinati per data, quindi non è come se potessi prendere l'ultima cella.

+0

Qualsiasi motivo per non riordinare la matrice per data, eseguire la funzione e quindi invertire l'ordine se lo si desidera? –

risposta

7

Ecco un'opzione. Vorrei anche raccomandare di usare NA s se invece 0 perché 0 potrebbe essere il prezzo reale.

library(dplyr) 
df %>% 
    arrange(as.Date(Date, format = "%d/%m/%Y")) %>% 
    group_by(Project) %>% 
    mutate(lastPrice = lag(price)) 

# Source: local data frame [5 x 4] 
# Groups: Project 
# 
# Project  Date price lastPrice 
# 1  B 22/2/2013 1642  NA 
# 2  B 19/3/2013 1567  1642 
# 3  A 30/3/2013 2082  NA 
# 4  C 12/4/2013 1575  NA 
# 5  C 5/6/2013 1582  1575 

Un'altra opzione è quella di utilizzare shift da the devel version di data.table

library(data.table) ## v >= 1.9.5 
setDT(df)[order(as.Date(Date, format = "%d/%m/%Y")), 
       lastPrice := shift(price), 
       by = Project] 

# Project  Date price lastPrice 
# 1:  A 30/3/2013 2082  NA 
# 2:  B 19/3/2013 1567  1642 
# 3:  B 22/2/2013 1642  NA 
# 4:  C 12/4/2013 1575  NA 
# 5:  C 5/6/2013 1582  1575 

Oppure con base R

df <- df[order(df$Project, as.Date(df$Date, format = "%d/%m/%Y")), ] 
within(df, lastPrice <- ave(price, Project, FUN = function(x) c(NA, x[-length(x)]))) 
# Project  Date price lastPrice 
# 1  A 30/3/2013 2082  NA 
# 3  B 22/2/2013 1642  NA 
# 2  B 19/3/2013 1567  1642 
# 4  C 12/4/2013 1575  NA 
# 5  C 5/6/2013 1582  1575 

Come nota a margine, è meglio mantenere la colonna della data in una classe Date in primo luogo, quindi mi raccomando di fare una volta per tutte df$Date <- as.Date(df$Date, format = "%d/%m/%Y").

+1

Questo funziona! E davvero pulito ... Grazie mille! :) – UD1989

+1

Peccato Non posso dare un +1 separato per la risposta e un altro per l'eccellente consiglio sull'impostazione delle date per la classe Date'. –

Problemi correlati