2015-07-08 7 views
5

Przepraszam, jeśli wcześniej zostało to zadane, ale nie mogłem znaleźć żadnego pytania, które by to dokładnie odpowiadało. Mam dane tak:Uzyskaj dane (t-1) w grupach

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 

chcę mieć kolumnę z cenami w ostatniej instancji przez grupę. Na przykład, dla rzędu 2, ostatnia instancja cena dla tej samej grupy będzie 1642. Dane końcowe będzie wyglądać mniej więcej tak:

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 

Jak to zrobić? Głównym problemem, przed którym stoję, jest to, że dane mogą nie być uporządkowane według daty, więc nie jest tak, że mogę po prostu wziąć ostatnią komórkę.

+0

Dowolny powód, dla którego nie chcesz ponownie uporządkować tablicy według daty, uruchomić funkcję, a następnie w razie potrzeby zmienić kolejność? –

Odpowiedz

7

Oto opcja. Zalecam również użycie NA s, jeśli 0 ponieważ 0 może być rzeczywistą ceną.

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 

Innym rozwiązaniem jest użycie shift z the devel version z 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 

lub z zasady 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 

Na marginesie lepiej jest zachować najpierw kolumnę z datą w klasie Date, więc raz na zawsze polecam zrobienie df$Date <- as.Date(df$Date, format = "%d/%m/%Y").

+1

To działa! I reallly schludne .. Dzięki za tonę! :) – UD1989

+1

Szkoda, nie mogę dać osobnej +1 dla odpowiedzi, a drugiej za doskonałą radę na temat ustawiania dat na klasie "Date". –