2016-04-18 27 views
1

我正在尋找一種能夠高效生成下面顯示的輸出的R解決方案。我可以很容易地在SAS中使用保留語句和幾行if-then-else邏輯等產生這些信息,但我在Rforum或本網站的存檔中找不到類似 。以下是我試圖應用於生成以下輸出表的邏輯。 謝謝你的幫助!使用R創建2個新變量,條件是保留先前行的值

如果ID是遇到的第一個ID,那麼group = 1和groupdate = date或否則如果不是first ID和date--上一個日期> 10或日期 - previous group date> 10 then group = previous group#+ 1和groupdate =日期或如果不是第一個ID和日期 - 前一個日期< = 10或日期 - 前一個羣組日期< = 10然後group =前一個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 
+1

請檢查GROUP 2的ID。這沒什麼意義。 – akrun

+0

我寫出的前哨表是正確的。問題出在我的邏輯 - 我省略了一小部分,因此我現在更新..下面是正確的邏輯。 – Pele

+0

如果ID是遇到的第一個ID,那麼group = 1和groupdate = date或者如果不是第一個ID和日期 - 先前日期> 10或日期 - 先前的組日期> 10然後group = previous group#+ 1和groupdate = date否則如果不是第一個ID和日期 - 前一個日期<= 10或日期 - 前一個組日期<= 10那麼group =前一個組#和groupdate =前一個日期。 – Pele

回答

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 
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 
+0

嗨akrun,我已經更新表的邏輯來利用新創建的組日期(見上文)。我如何將它合併到你的代碼中?感謝幫助! – Pele

相關問題