2016-06-02 4 views
1

내 데이터 프레임을 그렇지 않으면 동일한 행으로 검사하지만 날짜에서 1을 뺀 함수가 필요할 경우 true을 반환하는 함수가 필요합니다. 대용량 데이터 프레임이므로 최대한 효율적으로 처리하고 싶습니다.동일한 행, 날짜에서 1을 뺀 것이 있는지 확인하는 함수

는 예를 들어, 다음의 데이터 프레임을 가지고 : 함수가 Timmy|01/Jan/2016이 존재하는지 확인 Timmy|02/Jan/2016 표시되어야

name |date  
Timmy |01/Jan/2016 
Timmy |02/Jan/2016 
Timmy |03/Jan/2016 
Sally |04/Jan/2016 
Johnny|13/Feb/2016 
Johnny|29/Mar/2016 

, 그리고 true를 반환한다. 그 결과 데이터 프레임은 다음과 같이 보일 것이다 :

name |date  |hasDateMinusOne 
Timmy |01/Jan/2016|false 
Timmy |02/Jan/2016|true 
Timmy |03/Jan/2016|true 
Sally |04/Jan/2016|false 
Johnny|13/Feb/2016|false 
Johnny|29/Mar/2016|false 

This is the closest answer I've found.이 해들리 응답했지만, 그것은 5 세 그리고 dplyr 선행한다. 그것이 여전히 1,000,000 개 이상의 행을 처리하는 가장 효율적인 방법인지 궁금합니다.

감사합니다! 숀

답변

2

당신은 날짜와 같은 형식 date, 당신은 단지 하나를 뺄 수 있다면

는 :

library(dplyr) 

df %>% group_by(name) %>% 
    mutate(date = as.Date(date, '%d/%b/%Y'), 
      hasDateMinusOne = (date - 1) %in% date) 

# Source: local data frame [6 x 3] 
# Groups: name [3] 
# 
#  name  date hasDateMinusOne 
# (fctr)  (date)   (lgl) 
# 1 Timmy 2016-01-01   FALSE 
# 2 Timmy 2016-01-02   TRUE 
# 3 Timmy 2016-01-03   TRUE 
# 4 Sally 2016-01-04   FALSE 
# 5 Johnny 2016-02-13   FALSE 
# 6 Johnny 2016-03-29   FALSE 
+0

고맙습니다! 그랬어. –

1

우리는 base R 사용하여이 작업을 수행 할 수 있습니다. transform을 사용하여 '날짜'클래스를 '12 '로 변환 한 다음 ave'이름 '으로 그룹화하고 이전 날짜가 %in%'날짜 '열인지 확인하십시오.

df <- transform(df, date = as.Date(date, "%d/%b/%Y")) 
df$hasDateMinusOne <- with(df, !!ave(as.integer(date), name, 
      FUN = function(x) (x-1) %in% x)) 

효율성 문제 경우, 또 다른 옵션은 data.table입니다. 'data.frame'을 'data.table'(setDT(df))로 변환하고 'date'클래스를 'name'으로 그룹화 한 다음 이전 날짜가 'date'열 %in%인지 확인합니다.

setDT(df)[, date := as.Date(date, '%d/%b/%Y') 
    ][, hasDateMinusOne := (date-1) %in% date, by = name] 
df 
#  name  date hasDateMinusOne 
#1: Timmy 2016-01-01   FALSE 
#2: Timmy 2016-01-02   TRUE 
#3: Timmy 2016-01-03   TRUE 
#4: Sally 2016-01-04   FALSE 
#5: Johnny 2016-02-13   FALSE 
#6: Johnny 2016-03-29   FALSE 
관련 문제