2015-06-28 15 views
18

Bir veri çerçevesinde, ikinci veri çerçevesinden veri ayıklamak amacıyla ikinci bir veri çerçevesindeki en yakın zaman damgasıyla eşleştirmeye çalıştığım bir zaman damgası var. Benim yaklaşımın genel bir örnek için aşağıya bakınız: Bu iyi çalışırBaşka bir veri kümesinde en çok zamana göre eşlenen verileri eşleştirin. Düzgün vektör? Daha hızlı yol?

library(lubridate) 

data <- data.frame(datetime=ymd_hms(c('2015-04-01 12:23:00 UTC', '2015-04-01 13:49:00 UTC', '2015-04-01 14:06:00 UTC' ,'2015-04-01 14:49:00 UTC')), 
        value=c(1,2,3,4)) 
reference <- data.frame(datetime=ymd_hms(c('2015-04-01 12:00:00 UTC', '2015-04-01 13:00:00 UTC', '2015-04-01 14:00:00 UTC' ,'2015-04-01 15:00:00 UTC', '2015-04-01 16:00:00 UTC')), 
         refvalue=c(5,6,7,8,9)) 

data$refvalue <- apply(data, 1, function (x){ 
    differences <- abs(as.numeric(difftime(ymd_hms(x['datetime']), reference$datetime))) 
    mindiff <- min(differences) 
    return(reference$refvalue[differences == mindiff]) 
}) 

data 
#    datetime value refvalue 
# 1 2015-04-01 12:23:00  1  5 
# 2 2015-04-01 13:49:00  2  7 
# 3 2015-04-01 14:06:00  3  7 
# 4 2015-04-01 14:49:00  4  8 

, çok yavaş dışında referans dataframe benim gerçek dünya uygulamasında oldukça büyük olduğu için. Bu kod düzgün bir şekilde vektörlenmiş mi? Bu operasyonu gerçekleştirmenin daha hızlı, daha zarif bir yolu var mı?

+0

Python'da, numpy.searchsorted işlevinin tam olarak ne için olduğu budur. Ben bir R eşdeğeri aradım ama şu ana kadar bir tane bulamıyorum .. – cxrodgers

+0

@cxrodgers: Bu işleve bu işlevin bir uygulamasını görmek ilginç olurdu. Tis belgelerine baktıktan sonra, bunu nasıl yapacağımı merak ederek kafamı çiziyorum. Çok çalışan bir örnek bulabilir misin? –

+0

@BondedBu Rico'nun sağladığı yanıtı şu adreste bulabilirsiniz: http://stackoverflow.com/questions/8914491/finding-the-nearest-value-and-return-the-index-of-array-in-python – cxrodgers

cevap

15

kullanarak katılmak data.table s haddeleme deneyebilirsiniz, ama bir baz-R vectorized çözüm hangi apply versiyonundan daha iyi performans göstermelidir. Ve aslında hiç bir mesafeyi hesaplayamadığı için, aslında data.table-en yakın yaklaşımdan daha hızlı olabilir. Bu, aralıkların orta noktalarının uzunluğunu mümkün olan en düşük değere veya aralıkların başlangıç ​​aralığına ekleyerek bir "ara kesmeler" kümesi oluşturur ve daha sonra süreleri işlemek için findInterval işlevini kullanır. Bu, reference veri kümesinin satırlarına uygun bir dizin oluşturur ve "geri dönüş" daha sonra data nesnesine "aktarılabilir".

data$reefvalue <- reference$refvalue[ 
         findInterval(data$datetime, 
            c(-Inf, head(reference$datetime,-1))+ 
            c(0, diff(as.numeric(reference$datetime))/2)) ] 
# values are [1] 5 7 7 8 
+0

Bir demet teşekkürler. Bu iyi çalışıyor. – user278411

15

Bu hız için bir data.table çözüm eşleşecek mümkün olacaktır merak ettim "en yakın" seçeneğini

library(data.table) # v1.9.6+ 
setDT(reference)[data, refvalue, roll = "nearest", on = "datetime"] 
# [1] 5 7 7 8 
+1

Tek satır (indeks elde edilmeden): 'setDT (data) [, refvalue: = setkey (setDT (referans), datetime) [data, refere, roll =" en yakın "]]' - hayır ile birleştiğinde bu daha güzel olur Anahtarlar uygulanmaktadır. – Arun

+0

@Arun teşekkürler, yine de iki adım bana daha okunaklı görünüyor olsa da ... –

+0

Elbette. Katılıyorum. – Arun

İlgili konular