2015-10-16 149 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)

相關問題