2013-07-24 2 views
4

나는 500 만개의 이벤트 발생 시간을 포함하는 행렬 events을 가지고 있습니다. 이 500 만개의 이벤트는 각각 1에서 2000 사이의 "유형"을 가지고 있습니다. 매트릭스의 매우 단순화 된 버전은 아래와 같습니다. '시간'의 단위는 1970 년 이후 초입니다. 모든 이벤트는 2012 년 1 월 1 일 이후에 발생했습니다. 5 분 간격으로 발생 횟수를 빠르게 계산할 수 있습니까?

>events 
     type   times 
     1   1352861760 
     1   1362377700 
     2   1365491820 
     2   1368216180 
     2   1362088800 
     2   1362377700 

나는 5 분 버킷으로 2012 년 1 월 이후의 시간을 분할 한 후 각 버킷에 발생 방법 유형 i의 각 이벤트의 많은 이러한 각각의 버킷을 채우기 위해 노력하고 있어요. 내 코드는 아래와 같습니다. types은 1-2000의 가능한 유형을 모두 포함하는 벡터이며 by은 300으로 설정됩니다. 이는 5 분 안에 몇 초가 걸리기 때문입니다.

for(i in 1:length(types)){ 
    local <- events[events$type==types[i],c("type", "times")] 
    assign(sprintf("a%d", i),table(cut(local$times, breaks=seq(range(events$times)[1],range(events$times)[2], by=300)))) 
} 

이 변수를 5 분 버킷 각각이 얼마나 많이 발생 형 i의 행 벡터를 포함 a2000 통해 a1 초래한다.

나는 'a1'과 'a2000'사이의 모든 pairwise 상관 관계를 찾습니다.

위에서 제공 한 코드 청크를 최적화 할 수있는 방법이 있습니까? 그것은 매우 느리게 실행되지만, 나는 그것을 더 빨리 만드는 방법을 생각할 수 없다. 아마도 너무 많은 버킷과 너무 적은 시간이있을 것입니다.

모든 통찰력을 주시면 감사하겠습니다.

재현 예 : 위

>head(events) 
    type   times 
     12   1308575460 
     12   1308676680 
     12   1308825420 
     12   1309152660 
     12   1309879140 
     25   1309946460 

xevents <- xts(events[,"type"],.POSIXct(events[,"times"])) 
ep <- endpoints(xevents, "minutes", 5) 
counts <- period.apply(xevents, ep, tabulate, nbins=length(types)) 

>head(counts) 
         1 2 3 4 5 6 7 8 9 10 11 12 13 14 
2011-06-20 09:11:00 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
2011-06-21 13:18:00 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
2011-06-23 06:37:00 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
2011-06-27 01:31:00 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
2011-07-05 11:19:00 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
2011-07-06 06:01:00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

>> ep[1:20] 
[1] 0 1 2 3 4 5 6 7 8 9 10 12 20 21 22 23 24 25 26 27 

내가 사용하고 코드이지만, 문제는 5 분으로 증가하지 않았 음이다 : 그것은 단지 실제 사건의 발생에 의해 증가시킨다.

+0

"재생산 가능한 예제"(http://stackoverflow.com/q/5963269/271616)는 출력물을 원하는대로 표시하지 않습니다. 그렇지만 실제로는 해당 간격에 데이터가 있는지 여부에 관계없이 5 분마다 관찰 할 때 행을 원한다고 가정합니다. –

답변

3

이 경우 xts 패키지를 사용합니다. 겹치지 않는 5 분 간격으로 함수를 실행하는 것은 period.applyendpoints 함수를 사용하면 쉽게 수행 할 수 있습니다.

# create sample data 
library(xts) 
set.seed(21) 
N <- 1e6 
events <- cbind(sample(2000, N, replace=TRUE), 
    as.POSIXct("2012-01-01")+sample(1e7,N)) 
colnames(events) <- c("type","times") 
# create xts object 
xevents <- xts(events[,"type"], .POSIXct(events[,"times"])) 
# find the last row of each non-overlapping 5-minute interval 
ep <- endpoints(xevents, "minutes", 5) 
# count the number of occurrences of each "type" 
counts <- period.apply(xevents, ep, tabulate, nbins=2000) 
# set colnames 
colnames(counts) <- paste0("a",1:ncol(counts)) 
# calculate correlation 
#cc <- cor(counts) 

업데이트 영업 이익의 의견/편집에 응답하기 : 500 만 개 기록을 가진

# Create a sequence of 5-minute steps, from the actual start of the data 
m5 <- seq(round(start(xevents),'mins'), end(xevents), by='5 mins') 
# Create a sequence of 5-minute steps, from the start of 2012-01-01 
m5 <- seq(as.POSIXct("2012-01-01"), end(xevents), by='5 mins') 
# merge xevents with empty 5-minute xts object, and 
# subtract 1 second, so endpoints are at end of each 5-minute interval 
xevents5 <- merge(xevents, xts(,m5-1)) 
ep5 <- endpoints(xevents5, "minutes", 5) 
counts5 <- period.apply(xevents5, ep5, tabulate, nbins=2000) 
colnames(counts5) <- paste0("a",1:ncol(counts5)) 
# align to the beginning of each 5-minute interval, if you want 
counts5 <- align.time(counts5,60*5) 
+0

이 코드는 훌륭합니다! 지금까지 xts 라이브러리에 대해 알지 못했습니다. .POSIXct 단계는, 그러나, 내 날짜를 잘못 변환하고 계산 착오로 연결됩니다 ... 어떤 문제를 해결하는 방법? – user2588829

+0

@ user2588829 : 당신이 덜 모호하다면 그것을 고치는 법을 알고 싶습니다 ... "내 날짜를 잘못 변환하는 것"은 나에게 아무것도 알려주지 않습니다. –

+0

잘, .POSIXct 함수를 사용하여 변환 (정확하게 사용하고있는 함수는'as.POSIXct (strptime (x, format = "% m/% d/% y % H : % M : % S" tz = "GMT"), 원점 = "1970-01-01")')은 원래 있던 것을 만들고 있습니다 11/14/2012 02:56 1970-01-07 14:28:44. – user2588829

1

cutrangetimes 범위 내입니다. 그런 다음 table 또는 xtabs을 사용하여 표로 만들 수 있지만 전체 데이터 세트의 경우 표본을 생성 할 수 있습니다. 다음과 같은 뭔가 : 당신이 drop.unused.levels 여부를 원하는 경우

r <- trunc(range(events$times)/300) * 300 
events$times.bin <- cut(events$times, seq(r[1], r[2] + 300, by=300)) 
xtabs(~type+times.bin, events, drop.unused.levels=T) 

가 결정합니다. 이러한 종류의 데이터를 사용하면 sparse 행렬을 만들 수도 있습니다.

+0

500 만 행으로 실행 해 보셨습니까?내 컴퓨터가 1 백만 달러를 돌리려고했을 때 잠겨 있기 때문에 물어 본다. –

+0

@JoshuaUlrich : 아니,하지 않았다. '스파 스 = T '를 사용 했습니까? – krlmlr

3

은 아마 data.table를 사용합니다. 당신은 이것을 다음과 같이 할 수 있습니다 :

# First we make a sequence of the buckets from initial time to at least the end time + 5 minutes 
buckets <- seq(from = min(df$times) , by = 300 , to = max(df$times)+300) 

require(data.table) 
DT <- data.table(df) 

# Work out what bucket each time is in 
DT[ , list(Bucket = which.max(times <= buckets)) , by = "times" ] 

# Aggregate events by type and time bucket 
DT[ , list(Count = length(type)) , by = list(type, bucket) ] 
    type bucket Count 
1: 1  1  1 
2: 1 31721  1 
3: 2 42102  1 
4: 2 51183  1 
5: 2 30758  1 
6: 2 31721  1 
관련 문제