2015-01-21 23 views
5

Tôi có hai khung dữ liệu với mỗi hàng cho mỗi ID. Tôi cần trả lại ngày gần nhất và dữ liệu liên quan từ khung dữ liệu thứ hai dựa trên ID và ngày của khung dữ liệu đầu tiên - thêm dữ liệu có liên quan vào khung dữ liệu đầu tiên. Điều này cũng phải làm việc với NA s hiện diện trong khung dữ liệu thứ hai. dữ liệu Ví dụ:Hợp nhất ngày gần nhất và các biến có liên quan từ một khung dữ liệu khác theo nhóm

set.seed(42) 
df1 <- data.frame(ID = sample(1:3, 10, rep=T), dateTarget=(strptime((paste 
    (sprintf("%02d", sample(1:30,10, rep=T)), sprintf("%02d", sample(1:12,10, rep=T)), 
    (sprintf("%02d", sample(2013:2015,10, rep=T))), sep="")),"%d%m%Y")), Value=sample(15:100, 10, rep=T)) 
df2 <- data.frame(ID = sample(1:3, 10, rep=T), dateTarget=(strptime((paste 
    (sprintf("%02d", sample(1:30,20, rep=T)), sprintf("%02d", sample(1:12,20, rep=T)), 
    (sprintf("%02d", sample(2013:2015,20, rep=T))), sep="")),"%d%m%Y")), ValueMatch=sample(15:100, 20, rep=T)) 

Something từ base thích hợp hơn - split và một hỗn hợp của gia đình apply?

Bảng cuối cùng sẽ giống như thế:

ID dateTarget Value dateMatch ValueMatch 
1 3 22-02-15 52 09-03-15   94 
2 1 29-12-14 18 06-12-14   88 
3 3 08-12-15 98 06-07-15   48 
4 2 14-01-13 52 08-04-13   77 
5 2 29-07-15 97 01-08-15   68 
6 3 30-05-13 91 01-04-13   85 
7 1 04-11-13 70 21-02-14   35 
8 2 15-06-15 98 01-08-15   68 
9 3 17-11-14 68 15-12-14   95 

T.B. Có cách nào tốt hơn để tạo ra các ngày ngẫu nhiên (không sử dụng seq.Date)?

+0

Đối với "T.B." của bạn bạn sẽ có thể điều chỉnh http://stackoverflow.com/questions/14720983/efficiently-generate-a-random-sample-of-times-and-dates-between-two-dates với một 'as.Date' tại kết thúc hàm (và, có lẽ là một 'định dạng' nếu bạn cần nó trong'% d-% m-% Y' trong khung dữ liệu) – hrbrmstr

+1

Bạn cũng có thể làm một cái gì đó như 'Sys.Date() + sample (-1000 : 1000, 20) 'nếu bạn không quan tâm quá nhiều về ngày bắt đầu/kết thúc –

Trả lời

5

Dưới đây là giải pháp dựa trên các gói cơ sở:

z <- lapply(intersect(df1$ID,df2$ID),function(id) { 
    d1 <- subset(df1,ID==id) 
    d2 <- subset(df2,ID==id) 

    d1$indices <- sapply(d1$dateTarget,function(d) which.min(abs(d2$dateTarget - d))) 
    d2$indices <- 1:nrow(d2) 

    merge(d1,d2,by=c('ID','indices')) 
    }) 

z2 <- do.call(rbind,z) 
z2$indices <- NULL 

print(z2) 

# ID dateTarget.x Value dateTarget.y ValueMatch 
# 1 3 2015-11-14 47 2015-07-06   48 
# 2 3 2015-12-08 98 2015-07-06   48 
# 3 3 2015-02-22 52 2015-03-09   94 
# 4 3 2014-11-17 68 2014-12-15   95 
# 5 3 2013-05-30 91 2013-04-01   85 
# 6 1 2013-11-04 70 2014-02-21   35 
# 7 1 2014-12-29 18 2014-12-06   88 
# 8 2 2013-01-14 52 2013-04-08   77 
# 9 2 2015-07-29 97 2015-08-01   68 
# 10 2 2015-06-15 98 2015-08-01   68 
+0

Hoạt động thực sự. Tôi sẽ áp dụng cho các tập dữ liệu thực tế và làm việc thông qua sự hiểu biết nó tốt hơn. – Simon

5

Sử dụng data.table, đơn giản và thanh lịch giải pháp:

library(data.table) 

setDT(df1) 
setDT(df2) 

setkey(df2, ID, dateTarget)[, dateMatch:=dateTarget] 
df2[df1, roll='nearest'] 

    ID dateTarget ValueMatch dateMatch Value 
1: 3 2015-11-14   48 2015-07-06 47 
2: 3 2015-02-22   94 2015-03-09 52 
3: 1 2014-12-29   88 2014-12-06 18 
4: 3 2015-12-08   48 2015-07-06 98 
5: 2 2013-01-14   77 2013-04-08 52 
6: 2 2015-07-29   68 2015-08-01 97 
7: 3 2013-05-30   85 2013-04-01 91 
8: 1 2013-11-04   35 2014-02-21 70 
9: 2 2015-06-15   68 2015-08-01 98 
10: 3 2014-11-17   95 2014-12-15 68 
+0

Tốt. Tôi đã thử [data.table từ ví dụ này] (http://stackoverflow.com/questions/23342647/how-to-match-by-nearest-date-from-two-data-frames), nhưng đã bị mắc kẹt như thế nào sử dụng hai biến làm khóa. – Simon

+0

Đây là phần giới thiệu rất hay (đọc 10 phút) trình bày những gì bạn đã hỏi: http://cran.r-project.org/web/packages/data.table/vignettes/datatable-intro.pdf –

Các vấn đề liên quan