2015-06-04 11 views
8

Aşağıdaki sorunla karşılaşıyorum: bir data.table içinde örtüşmeyen aralıklarının bir kümesi verildiğinde, aralıklar arasındaki boşlukları bildirin.Verileri kullanarak aralıklar arasındaki boşlukları bulma

Bunu bir kez SQL'de uyguladım, ancak lead işlevi veya gecikme işlevinin olmaması nedeniyle data.table ile uğraşıyorum. Tamlık için, SQL kodu here var. İşlevlerin, data.table sürüm 1.9.5'te uygulandığını biliyorum. changelog tarafından. Yani bu çok fazla birleştirme yapmadan ve gecikme veya kurşun fonksiyonu olmadan data.table ile mümkün mü? Prensip olarak, performans sıkıntı çekmediği sürece birleştirme (aka birleştirmeler) kullanmaya tamamen karşı değilim. Bunun kolay bir uygulama olduğunu düşünüyorum, ancak önceki bitiş zamanımın boşluk tablosunun başlangıç ​​zamanı olarak nasıl “elde edileceğine” karar veremiyorum. Örneğin

:

ID    stime    etime 
1 2014-01-15 10:30:00 2014-01-15 11:00:00 
1 2014-01-15 12:00:00 2014-01-16 11:30:00 
2 2014-01-15 11:00:00 2014-01-15 12:30:00 
2 2014-01-15 12:45:00 2014-01-15 13:30:00 

Uyarı:

# The numbers represent seconds from 1970-01-01 01:00:01 
dat <- structure(
    list(ID = c(1L, 1L, 1L, 2L, 2L, 2L), 
     stime = structure(c(as.POSIXct("2014-01-15 08:00:00"), 
          as.POSIXct("2014-01-15 11:00:00"), 
          as.POSIXct("2014-01-16 11:30:00"), 
          as.POSIXct("2014-01-15 09:30:00"), 
          as.POSIXct("2014-01-15 12:30:00"), 
          as.POSIXct("2014-01-15 13:30:00") 
          ), 
         class = c("POSIXct", "POSIXt"), tzone = ""), 
     etime = structure(c(as.POSIXct("2014-01-15 10:30:00"), 
          as.POSIXct("2014-01-15 12:00:00"), 
          as.POSIXct("2014-01-16 13:00:00"), 
          as.POSIXct("2014-01-15 11:00:00"), 
          as.POSIXct("2014-01-15 12:45:00"), 
          as.POSIXct("2014-01-15 14:30:00") 
          ), 
         class = c("POSIXct", "POSIXt"), tzone = "") 
), 
    .Names = c("ID", "stime", "etime"), 
    sorted = c("ID", "stime", "etime"), 
    class = c("data.table", "data.frame"), 
    row.names = c(NA,-6L) 
) 

dat <- data.table(dat) 

Bu sonuçlanır boşluklar gün boyunca eşit olarak rapor edilir.

+2

Burada bir satır eksik değil misiniz yoksa bir şey mi özlüyorum? –

+3

yan not: 'dat <- data.table (dat)' hafıza kaybıdır .. 'setDT (dat) 'yerine kullanın. – Arun

+2

Sanırım bu, önceki Q.'ndaki @ eddi'nin cevabındaki küçük değişikliklerle yapılabilir – Arun

cevap

5

David'in cevabı bir varyasyonu, dışarı yazmaya eğilimlidir biraz daha az verimli ama daha basit:

setkey(dat, stime)[, .(stime=etime[-.N], etime=stime[-1]), by=ID] 

üretir:

ID    stime    etime 
1: 1 2014-01-15 10:30:00 2014-01-15 11:00:00 
2: 1 2014-01-15 12:00:00 2014-01-16 11:30:00 
3: 2 2014-01-15 11:00:00 2014-01-15 12:30:00 
4: 2 2014-01-15 12:45:00 2014-01-15 13:30:00 

setkey sadece emin tablo sıralanır yapmaktır zamanla.

5

Bir şey kaçırmıyorsam, istediğiniz çıktıda bir satır eksiksiniz, bu nedenle denediğiniz gibi devel sürümden shift'u kullanma girişimi.

library(data.table) ## v >= 1.9.5 
indx <- dat[, .I[-.N], by = ID]$V1 
dat[, .(ID, stimes = etime, etime = shift(stime, type = "lead"))][indx] 
res 
# ID    stime    etime 
# 1: 1 2014-01-15 10:30:00 2014-01-15 11:00:00 
# 2: 1 2014-01-15 12:00:00 2014-01-16 11:30:00 
# 3: 2 2014-01-15 11:00:00 2014-01-15 12:30:00 
# 4: 2 2014-01-15 12:45:00 2014-01-15 13:30:00