我有一个值为
的数据框cust_no name trans_date amount
1122 abc 2014-03-10 2000
1122 abc 2014-03-15 300
4444 pqr 2014-01-10 1000
4444 pqr 2014-01-15 1000
4444 pqr 2014-02-15 1000
7777 xyz 2014-01-10 34
7777 xyz 2014-01-11 444
7777 xyz 2014-01-17 2344
7777 xyz 2014-01-30 345
我希望计算相同客户的两笔交易之间的天差。我的输出应该像
cust_no name trans_date amount TimeDiff
1122 abc 2014-03-10 2000 0
1122 abc 2014-03-15 300 5
4444 pqr 2014-01-10 1000 0
4444 pqr 2014-01-15 1000 5
4444 pqr 2014-02-15 1000 30
7777 xyz 2014-01-10 34 0
7777 xyz 2014-01-11 444 1
7777 xyz 2014-01-17 2344 6
7777 xyz 2014-01-30 345 13
我尝试了以下代码(当然不使用diff()
)
> for( i in 1:(nrow(df)-1)){
+ if(ds$cust_no[i]==ds$cust_no[i+1]){
+ ds$TimeGap[i]<-ds$trans_Date[i+1]-ds$trans_Date[i]
+ }
+ }
但是我没有得到如上所示的所需输出。相反,我得到下面的一个,它基本上计算表的transaction_date的每个值之间的时间间隔,这从负值可以看出。
1122 abc 2014-03-10 2000 0
1122 abc 2014-03-15 300 5
4444 pqr 2014-01-10 1000 -64
4444 pqr 2014-01-15 1000 5
4444 pqr 2014-02-15 1000 30
7777 xyz 2014-01-10 34 -35
7777 xyz 2014-01-11 444 1
7777 xyz 2014-01-17 2344 6
7777 xyz 2014-01-30 345 13
答案 0 :(得分:3)
您可以使用ave
或包dplyr
或data.table
按组计算。
数据强>
df <- structure(list(cust_no = c(1122L, 1122L, 4444L, 4444L, 4444L,
7777L, 7777L, 7777L, 7777L), name = structure(c(1L, 1L, 2L, 2L,
2L, 3L, 3L, 3L, 3L), .Label = c("abc", "pqr", "xyz"), class = "factor"),
trans_date = structure(c(16139, 16144, 16080, 16085, 16116,
16080, 16081, 16087, 16100), class = "Date"), amount = c(2000L,
300L, 1000L, 1000L, 1000L, 34L, 444L, 2344L, 345L)), .Names = c("cust_no",
"name", "trans_date", "amount"), row.names = c(NA, -9L), class = "data.frame")
基础解决方案(来自@akrun)
df$time_diff <- with(df, ave(as.numeric(trans_date), cust_no, FUN=function(x) c(0, diff(x))))
dplyr解决方案
require(dplyr)
df %>% group_by(cust_no) %>% mutate(time_diff = c(0, diff(trans_date)))
data.table解决方案
require(data.table)
setDT(df)[, time_diff :=c(0, diff(trans_date)), by=cust_no][]