根据R中的标准获取先前日期

时间:2015-03-19 17:32:25

标签: r

我有以下数据。

df <- data.frame(CustID = c(1,2,3,4,5,1,5),
CustName = c("Fred","Maria","John","Mark", "Julia","Fred","Julia"),
ServiceDate = c('2010-11-1','2008-3-25','2007-3-14','2010-11-1','2008-3-25','2010-12-14','2008-3-14'), stringsAsFactors = F)

df$ServiceDate <- as.Date(df$ServiceDate, "%Y-%m-%d")

df

  CustID CustName ServiceDate
1      1     Fred  2010-11-01
2      2    Maria  2008-03-25
3      3     John  2007-03-14
4      4     Mark  2010-11-01
5      5    Julia  2008-03-25
6      1     Fred  2010-12-14
7      5    Julia  2008-03-14

我需要找出一种方法来获取基于CusID和ServiceDate的先前值,以便我得到这样的结果:

  CustID CustName ServiceDate PriorServiceDate
1      1     Fred  2010-11-01             <NA>
2      2    Maria  2008-03-25             <NA>
3      3     John  2007-03-14             <NA>
4      4     Mark  2010-11-01             <NA>
5      5    Julia  2008-03-25       2008-03-14
6      1     Fred  2010-12-14       2010-11-01
7      5    Julia  2008-03-14             <NA>

我尝试过使用sqldf但没有成功。谢谢。

3 个答案:

答案 0 :(得分:4)

使用dplyr我认为这可以解决您的问题。

library(dplyr)
df %>%
    group_by(CustID) %>%
    arrange(ServiceDate) %>%
    mutate(PriorServiceDate = lag(ServiceDate))

Source: local data frame [7 x 4]
Groups: CustID

  CustID CustName ServiceDate PriorServiceDate
1      1     Fred  2010-11-01             <NA>
2      1     Fred  2010-12-14       2010-11-01
3      2    Maria  2008-03-25             <NA>
4      3     John  2007-03-14             <NA>
5      4     Mark  2010-11-01             <NA>
6      5    Julia  2008-03-14             <NA>
7      5    Julia  2008-03-25       2008-03-14

请注意,这假设您使用lag查看前一个日期,而不是最短日期(不确定您的问题)。

如果您确实想要min,那么您可以轻松地将其他人编入索引

df2 <- df %>%
    group_by(CustID) %>%
    arrange(ServiceDate) %>%
    mutate(PriorServiceDate = min(ServiceDate))

df2$PriorServiceDate[which(df2$ServiceDate == df2$PriorServiceDate)] = NA

Source: local data frame [7 x 4]
Groups: CustID

  CustID CustName ServiceDate PriorServiceDate
1      1     Fred  2010-11-01             <NA>
2      1     Fred  2010-12-14       2010-11-01
3      2    Maria  2008-03-25             <NA>
4      3     John  2007-03-14             <NA>
5      4     Mark  2010-11-01             <NA>
6      5    Julia  2008-03-14             <NA>
7      5    Julia  2008-03-25       2008-03-14

答案 1 :(得分:2)

dplyr答案不同,它使用基数R并获得最小日期而不是滞后。

首先获得每位客户的第一个服务日期。

first.service <- with(df, aggregate(ServiceDate,
                                    by=list(CustID=CustID, CustName=CustName),
                                    FUN=min))

现在将其与原始数据框合并。

both <- merge(df, first.service, by=c("CustID", "CustName"))

对于没有此类服务的客户,您可以将之前的服务日期设置为NA

both$x[with(both, ServiceDate == x)] <- NA

然后重命名列:

colnames(both)[4] <- "PriorServiceDate"

答案 2 :(得分:1)

使用sqldf可以使用左自连接完成。对于来自b的特定行,保留a的行CustID与来自CustID的{​​{1}}相同且其b更少。然后在那些ServiceDate行中选择a最大的行。这不会对输入的顺序做出任何假设。它保留了行的原始顺序,但如果这不重要,那么ServiceDate行可以省略:

order by

,并提供:

library(sqldf)

DF <- sqldf("select b.CustID, 
                    b.CustName, 
                    b.ServiceDate ServiceDate__Date, 
                    max(a.ServiceDate) PriorDate__Date
             from df b 
             left join df a 
               on b.ServiceDate > a.ServiceDate and b.CustID = a.CUSTID 
             group by b.CustID, b.ServiceDate
             order by b.rowid", 
        method = "name__class")