我正在寻找能够有效生成如下所示输出的R解决方案。我可以使用retain语句和几行if-then-else逻辑等在SAS中轻松生成这个。但我找不到类似的东西 在Rforum或本网站的档案中。下面是我试图应用于生成下面的输出表的逻辑。 在任何帮助下谢谢!
如果ID是遇到的第一个ID,那么group = 1和groupdate = date,否则如果不是第一个ID和日期 - 上一个日期> 10或日期 - 上一组日期> 10然后组=前一组#+ 1和groupdate =日期或否则如果不是第一个ID和日期 - 上一个日期< = 10或日期 - 上一个组日期< = 10然后组=上一个group#和groupdate =上一个日期。
输入:
ID DATE ITEM
1 1/1/2014 P1
1 1/15/2014 P2
1 1/20/2014 P3
1 1/22/2014 P4
1 3/10/2015 P5
2 1/13/2015 P1
2 1/20/2015 P2
2 1/28/2015 P3
2 2/28/2015 P4
2 3/20/2015 P5
期望输出
ID DATE ITEM GROUP GROUPDATE
1 1/1/2014 P1 1 1/1/2014
1 1/15/2014 P2 2 1/15/2014
1 1/20/2014 P3 2 1/15/2014
1 1/22/2014 P4 2 1/15/2014
1 3/10/2015 P5 3 3/10/2015
2 1/13/2015 P1 1 1/13/2015
2 1/20/2015 P2 1 1/13/2015
2 1/28/2015 P3 2 1/28/2015
2 2/28/2015 P4 3 2/28/2015
2 3/20/2015 P5 4 3/20/2015
答案 0 :(得分:2)
我们可以使用data.table
library(data.table)
setDT(df1)[, GROUP:={
dt <- as.Date(DATE, "%m/%d/%Y")
gr1 <-cumsum((dt-shift(dt, fill=dt[1L]))>10)+1L; list(gr1)} ,
by = ID]
df1[, GROUPDATE := DATE[1L] , by = .(GROUP, ID)]
df1
# ID DATE ITEM GROUP GROUPDATE
# 1: 1 1/1/2014 P1 1 1/1/2014
# 2: 1 1/15/2014 P2 2 1/15/2014
# 3: 1 1/20/2014 P3 2 1/15/2014
# 4: 1 1/22/2014 P4 2 1/15/2014
# 5: 1 3/10/2015 P5 3 3/10/2015
# 6: 2 1/13/2015 P1 1 1/13/2015
# 7: 2 1/20/2015 P2 1 1/13/2015
# 8: 2 1/28/2015 P3 1 1/13/2015
# 9: 2 2/28/2015 P4 2 2/28/2015
#10: 2 3/20/2015 P5 3 3/20/2015
答案 1 :(得分:0)
以下是另一种方法:
df <- read.table(header=T,text='ID DATE ITEM
1 1/1/2014 P1
1 1/15/2014 P2
1 1/20/2015 P3
1 1/22/2015 P4
1 3/10/2015 P5
2 1/13/2015 P1
2 1/20/2015 P2
2 1/28/2015 P3
2 2/28/2015 P4
2 3/20/2015 P5')
df$DATE <- as.Date(df$DATE,"%m/%d/%Y")
split.rows <- split.default(1:nrow(df),df$ID,drop=T)
lapply(split.rows,function(x){
split_df <- df[x,]
group <- vector('integer',length(x))
group_date <- vector('character',length(x))
group[1] <- 1
group_date[1] <- as.character(split_df[1,'DATE'])
for (i in 2:nrow(split_df)){
if (split_df[i,'DATE'] - split_df[i-1,'DATE'] >= 10){
group[i] <- group[i - 1] + 1
group_date[i] <- as.character(split_df[i,'DATE'])
}
else{
group[i] <- group[i - 1]
group_date[i] <- group_date[i-1]
}
}
df$GROUP[x] <<- group
df$GROUPDATE[x] <<- group_date
return(NULL)
})
> df
ID DATE ITEM GROUP GROUPDATE
1 1 2014-01-01 P1 1 2014-01-01
2 1 2014-01-15 P2 2 2014-01-15
3 1 2015-01-20 P3 3 2015-01-20
4 1 2015-01-22 P4 3 2015-01-20
5 1 2015-03-10 P5 4 2015-03-10
6 2 2015-01-13 P1 1 2015-01-13
7 2 2015-01-20 P2 1 2015-01-13
8 2 2015-01-28 P3 1 2015-01-13
9 2 2015-02-28 P4 2 2015-02-28
10 2 2015-03-20 P5 3 2015-03-20