2017-10-04 1 views
1

일일 데이터가 포함 된 데이터 테이블이 있습니다. 이 데이터 표에서 매주 수요일에 얻은 주별 데이터 포인트를 추출하려고합니다. 수요일이 공휴일 인 경우, 즉 데이터 표에서 사용할 수없는 경우 다음 사용 가능한 데이터 포인트를 사용해야합니다. 여기 MWE : 출력매일 데이터를 주간 데이터로 변환하고 휴일을 처리하십시오.

library(data.table) 
df <- data.table(date=as.Date(c("2012-06-25","2012-06-26","2012-06-27","2012-06-28","2012-06-29","2012-07-02","2012-07-03","2012-07-05","2012-07-06","2012-07-09","2012-07-10","2012-07-11","2012-07-12","2012-07-13","2012-07-16","2012-07-17","2012-07-18","2012-07-19","2012-07-20"))) 
df[,weekday:=strftime(date,'%u')] 

:

  date weekday 
1: 2012-06-25  1 
2: 2012-06-26  2 
3: 2012-06-27  3 
4: 2012-06-28  4 
5: 2012-06-29  5 
6: 2012-07-02  1 
7: 2012-07-03  2 
8: 2012-07-05  4 #here the 4th of July was skipped 
9: 2012-07-06  5 
10: 2012-07-09  1 
11: 2012-07-10  2 
12: 2012-07-11  3 
13: 2012-07-12  4 
14: 2012-07-13  5 
15: 2012-07-16  1 
16: 2012-07-17  2 
17: 2012-07-18  3 
18: 2012-07-19  4 
19: 2012-07-20  5 

내 원하는 결과는,이 경우에있을 것입니다 :

 date weekday 
2012-06-27  3 
2012-07-05  4 
2012-07-11  3 
2012-07-18  3 

가는 것보다이를 얻는보다 효율적인 방법이 있나요 일주일에 한 번씩 for 루프를 통해 수요일 데이터 포인트가 데이터에 포함되는지 여부를 확인합니다. 나는 더 나은 방법이 있어야한다고 생각합니다. 그래서 어떤 충고라도 깊게 평가 될 것입니다! (IMO의 제안 다음)

작업 용액 : 여기

df[,weekday:=wday(date)] #faster way to get weekdays, careful: numbers increased by 1 vs strftime 
df[,numweek:=floor(as.numeric(date-date[1])/7+1)] #get continuous week numbers extending over end of years 
df[df[,.I[which.min(abs(weekday-4.25))],by=.(numweek)]$V1] #gets result 

답변

1

인 그게 (3에 가장 가까운 값 (.I 사용)의 위치를 ​​찾는 data.table에 가입하여 하나 방법 2가 아니며 which.min(abs(as.integer(weekday)-3.25))을 사용).

df[df[, .I[which.min(abs(as.integer(weekday)-3.25))], by=week(date)]$V1] 
     date weekday 
1: 2012-06-27  3 
2: 2012-07-05  4 
3: 2012-07-11  3 
4: 2012-07-18  3 

실제 데이터가 연수 인 경우 by=.(week(date), year(date))을 사용해야합니다.


참고도 의지가 직접 주의 정수 하루를 반환하는 data.table 기능 wday이 있음. strftime에 의해 반환 된 문자 정수 값보다 1만큼 크기 때문에 직접 사용하려는 경우 조정이 필요합니다.

하나의 변수와 data.table에서

, 당신은 날짜가 이상과 일치하는지

df[, weekday := wday(date)] 
df[df[, .I[which.min(abs(weekday-4.25))], by=week(date)]$V1] 
     date weekday 
1: 2012-06-27  4 
2: 2012-07-05  5 
3: 2012-07-11  4 
4: 2012-07-18  4 

주의 할 것.

+0

감사합니다. @Imo,이 작품은 훌륭합니다. 남은 유일한 불행한 세부 사항은 연말에이 방법의 행동입니다 (내 데이터는 실제로 몇 년에 걸쳐 있음). 예 : 2010-12-29는 수요일이며 2011-01-05는 수요일이며 둘 다 공휴일이 아닙니다. 그러나 주 단위로 정렬하기 때문에 2010 년에도 시작된 주 단위가 남아 있으므로이 메서드는 2010-12-31 연도의 마지막 날도 반환합니다. 이를 방지 할 수있는 방법이 있습니까? 일부는 여전히 원할 수도 있기 때문에 매년 마지막 날짜를 모두 삭제하는 것은 상당히 위험 할 수 있습니다. – Daedalus

+0

이 서브 세트 이후에 날짜의 차이 (예 : dat [, dtDiff : = diff (date)])를 취하는 것이 가능한 해결책이 될 수 있습니다. 값이 5보다 작 으면 문제가있는 것입니다. 그런 행에 대해서는 수요일 (원래 설정에서 평일 == 3) 인 것을 선택하십시오. – lmo

관련 문제