2015-07-08 1 views
5

Извините, если это было задано ранее, но я не мог найти ответа на этот вопрос. У меня есть следующие данные:Получите данные (t-1) внутри групп

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 

Я хочу иметь колонку с ценами последней инстанции по группам. Например, для строки 2, последняя цена экземпляра для одной группы будет 1642. Окончательные данные будут выглядеть примерно так:

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 

Как это сделать? Основная проблема, с которой я сталкиваюсь, заключается в том, что данные не могут быть упорядочены по дате, поэтому не так, как будто я могу просто взять последнюю ячейку.

+0

Любые причины не переупорядочивать массив по дате, запустить вашу функцию, а затем, при желании, отменить порядок? –

ответ

7

Вот вариант. Я бы также рекомендовал использовать NA s, если 0, потому что 0 может быть фактической.

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 

Другой вариант заключается в использовании shift из the devel version из 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 

Или с основанием 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 

В качестве примечания стороны лучше сохранить колонку даты в классе Date в первую очередь, поэтому я бы рекомендовал делать df$Date <- as.Date(df$Date, format = "%d/%m/%Y") раз и навсегда.

+1

Это работает! И очень аккуратно ... Спасибо! :) – UD1989

+1

Жаль, что я не могу дать отдельный +1 для ответа, а другой - отличный совет относительно установки дат в класс 'Дата'. –