2016-12-07 3 views
4

찾기 나는 다음과 같은 데이터했습니다 :날짜 차이

ID GROUP  DATE 
A GR1 12/01/2013 
A GR1 09/04/2014 
A GR1 01/03/2015 
A GR2 04/04/2015 
A GR2 08/21/2015 
A GR1 01/05/2016 
A GR1 06/28/2016 
B GR2 11/01/2013 
B GR2 06/04/2014 
B GR2 04/15/2015 
B GR3 11/04/2015 
B GR2 03/21/2016 
B GR2 07/05/2016 
B GR1 06/28/2016 
C GR2 01/16/2014 
C GR2 06/04/2014 
C GR2 04/15/2015 
C GR3 11/04/2015 
C GR2 03/21/2016 
C GR2 06/05/2016 
C GR1 06/28/2016 

나는 사람이 각 그룹에 남아 차이를 싶어합니다. 그래서 새 테이블은 다음과 같이됩니다 : 398 열 "DIFF"의 값이 '01/03/2015 차이를 고려하여오고있다

ID GROUP  DATE  Diff 
A GR1 12/01/2013 
A GR1 09/04/2014 
A GR1 01/03/2015 398 
A GR2 04/04/2015 
A GR2 08/21/2015 139 
A GR1 01/05/2016 
A GR1 06/28/2016 175 
B GR2 11/01/2013 
B GR2 06/04/2014 
B GR2 04/15/2015 530 
B GR3 11/04/2015 
B GR2 03/21/2016 
B GR2 07/05/2016 106 
B GR1 06/28/2016 
C GR2 01/16/2014 
C GR2 06/04/2014  
C GR2 04/15/2015 454 
C GR3 11/04/2015 
C GR2 03/21/2016 
C GR2 01/05/2016 76 
C GR1 06/28/2016 

'- '12// 2013 (1)를 제공합니다. 비슷하게 다른 모든 차이.

이제 제 질문은이 차이를 얻는 방법입니다. 그룹이 다른 기간에 반복하기 때문에 각 그룹에서 최대 (날짜) - 최소 (최대)를 취할 수 없습니다. 마찬가지로 SAS에서는 첫 번째 점과 마지막 점을 사용할 수 없습니다.

누군가가 해결책을 도우려는 경우 매우 감사드립니다. 데이터 크기가 매우 커서 SAS 솔루션을 선호합니다. 그래서 기억이 안 간다.

감사합니다,

+0

@RichScriven : 귀하의 의견에 감사드립니다. 하지만 어떻게하는지 말해 주실 수 있습니까? 데이터 크기가 너무 커서 메모리에 저장되지 않으므로 sas를 선호합니다. – Beta

답변

6
library(dplyr) 
library(data.table) 
df$xxx = rleidv(df[, c("ID","GROUP"),with = FALSE ]) 
df$DATE = as.Date(df$DATE, format = "%m/%d/%Y") 
df %>% group_by(xxx) %>% mutate(diff = max(DATE) - min(DATE)) %>% 
     ungroup(xxx) %>% mutate(xxx = NULL) 
#  ID GROUP  DATE  diff 
# <chr> <chr>  <date> <time> 
#1  A GR1 2013-12-01 398 days 
#2  A GR1 2014-09-04 398 days 
#3  A GR1 2015-01-03 398 days 
#4  A GR2 2015-04-04 139 days 
#5  A GR2 2015-08-21 139 days 
#6  A GR1 2016-01-05 175 days 
#7  A GR1 2016-06-28 175 days 
#8  B GR2 2013-11-01 530 days 
#9  B GR2 2014-06-04 530 days 
#10  B GR2 2015-04-15 530 days 

data.table 사용 :

library(data.table) 
df[, diff := max(DATE)-min(DATE),by = c("xxx")][,xxx:=NULL] 
+0

답변 해 주셔서 감사합니다. 당신의 대답은 내 질문에 대해 완벽하게 설명했다. 하지만 저는 리치의 대답을 기다리기를 원합니다. 그는 답을 수락하기 전에 먼저 해결책을 제시했습니다. 희망하지 않습니다. 조엘 다시 한번 고마워! – Beta

+0

@Beta 만약 우리가 다음 ID가 같은 그룹으로 시작하면 우리는 문제를 일으킬 런 ('df $ xxx = rleid (df $ GROUP)')을 찾으려면 GROUP 만 사용하면 –

+1

입니다. 이 특정 데이터에서 그룹은 ID가 변경 되어도 항상 변경되므로 발생하지 않았습니다. –

2
data want(drop=_:); 
    merge have have(firstobs=2 rename=(id=_id group=_group date=_date)); 
    retain _temp; 
    _temp= min(_temp,date); 
    if id^=_id or group^=_group then do; 
     diff=intck('day',_temp,date); 
     if diff=0 then call missing(diff); 
     _temp=_date; 
    end; 
run; 
+0

답변 해 주셔서 감사합니다. – Beta

5

SAS와 함께 그 일을 사소한입니다. RETAIN을 사용하여 그룹의 첫 번째 레코드에서 시작 날짜를 유지하십시오. 데이터가 정렬 된 것처럼 보이지 않으므로 먼저 정렬하거나 현재 순서를 유지하려면 (그룹 내의 레코드가 이미 날짜순으로 정렬되어 있음) BY 문에 NOTSORTED 옵션을 사용할 수 있습니다.

data want ; 
    set have ; 
    by id group notsorted; 
    if first.group then start = date ; 
    else if last.group then diff = date - start ; 
    retain start; 
    drop start; 
run; 

당신은 현재의 순서를 유지해야하지만 날짜가 그 분을 발견하고 최대 당신이 다른 변수와 조금 더 로직을 추가해야합니다 그룹 내에서 날짜에, 그룹 내에서 분류되지 않은 경우.

data want ; 
    set have ; 
    by id group notsorted; 
    if first.group then start = date ; 
    if first.group then stop = date ; 
    start = min(start,date); 
    stop = max(stop,date); 
    if last.group and not first.group then diff = stop - start ; 
    retain start stop; 
    drop start stop; 
run; 
+0

톰 감사합니다. 실제로 "정렬되지 않은"옵션을 사용하지 않았다는 것을 제외하고는 제안한 것과 같은 방식으로 작업했습니다. 나는 그것을 알지 못했다. 이것은 훌륭한 학습입니다! 다시 한 번 감사드립니다! – Beta