2015-10-16 133 views
2

我想添加一列表示第0123列之间的数据差异。第n行和m第col。 n+1排。R:第(n + 1)行第n行第m + 1列与第(n + 1)行第m列之间的日期差

的数据格式是作为df

set.seed(2) 
user.list = c('A','B','C') 
t = seq(as.Date("2015/1/1"), as.Date("2015/12/31"), 'days') 
st = sort(sample(t, 10)) 
et = st+30 
df = data.frame(
     user=sort(sample(user.list, 10, replace=T)), 
     start=st, 
     due=et 
    ) 

预期的输出应当是

user  start  due  td 
1  A 2015-02-16 2015-03-18 -16 
2  A 2015-03-02 2015-04-01 -23 
3  A 2015-03-09 2015-04-08  70 
4  A 2015-06-17 2015-07-17 197* 
5  B 2015-07-15 2015-08-14 -17 
6  B 2015-07-28 2015-08-27  17 
7  B 2015-09-13 2015-10-13 109* 
8  C 2015-10-26 2015-11-25  11 
9  C 2015-12-06 2016-01-05 -29 
10 C 2015-12-07 2016-01-06  24* 

td表示一天中的单元的时间差。 例如,对于用户A,-16由2015-03-02和2015-03-18之间的差异导出; -23是2015-03-09和2015-04-01之间的差额等。*的数字是每个用户的最后一行,也可以从固定日期2016-01-30和2015之间的差异中导出-07-17(用户A)。

怎样才可以通过一种有效的方式,而不dlply(分用户的列表),forif(扫描每一行,看看它是否是用户的最后一个)解决了吗?

回答

2

随着dplyr

library(dplyr) 
df %>% group_by(user) %>% 
    mutate(start = c(start, as.Date("2016-01-30"))[-1]) %>% 
    mutate(td = start - due) 
# Source: local data frame [10 x 4] 
# Groups: user [3] 
# 
#  user  start  due  td 
# (fctr)  (date)  (date) (dfft) 
# 1  A 2015-03-02 2015-03-18 -16 days 
# 2  A 2015-03-09 2015-04-01 -23 days 
# 3  A 2015-06-17 2015-04-08 70 days 
# 4  A 2016-01-30 2015-07-17 197 days 
# 5  B 2015-07-28 2015-08-14 -17 days 
# 6  B 2015-09-13 2015-08-27 17 days 
# 7  B 2016-01-30 2015-10-13 109 days 
# 8  C 2015-12-06 2015-11-25 11 days 
# 9  C 2015-12-07 2016-01-05 -29 days 
# 10  C 2016-01-30 2016-01-06 24 days 

如果你想坚持base R,类似的事情:

start <- ave(df$start, df$user, FUN=function(x) c(x, as.Date("2016-01-30"))[-1]) 
df$td <- start - df$due 

如果你想要做的事情一样添加星星,并采取了“天”单位,你可以相应地调整。 (即sub(" .*", "", df$td)

相关问题