簡體   English   中英

在data.table中選擇最接近的成對匹配

[英]Selecting nearest pairwise match in data.table

我有一個R data.table,其結構如下:

> str(dat)
Classes ‘data.table’ and 'data.frame':  26802896 obs. of  4 variables:
 $ id : chr  ...
 $ date1 : Date, format: "2011-12-15" "2012-11-02" ...
 $ date2: Date, format: "2010-08-15" "2011-01-04" ...
 $ row_name : chr  ...

我的目標是創建一個新的變量matching_row_name ,其行的行名稱由id date1-date2>0 days & date1-date2<30 daysdate1-date2>0 days & date1-date2<30 days 在多個匹配的情況下,我想使用min(date1-date2)row_name作為匹配變量。 沒有聯系。

我制作了一個可復制的示例數據data.table ,如下所示:

latemail <- function(N, st="2012/01/01", et="2013/12/31") {
  st <- as.POSIXct(as.Date(st))
  et <- as.POSIXct(as.Date(et))
  dt <- as.numeric(difftime(et,st,unit="sec"))
  ev <- sort(runif(N, 0, dt))
  rt <- st + ev
}
set.seed(1)
date1=latemail(1000, st="2012/01/01", et="2013/12/31")
set.seed(2)
date2=latemail(1000, st="2012/01/02", et="2013/12/31")
set.seed(3)
ids=sample(letters[1:10],100,replace=TRUE)
dat=data.table(date1=date1,date2=date2,id=ids,row_name=seq(1:1000))
dat=dat[date1<date2]

看起來像這樣

> dat
                   date1               date2 id row_name
  1: 2012-01-01 18:01:58 2012-01-02 06:36:13  b        1
  2: 2012-01-02 03:10:54 2012-01-03 14:57:18  i        2
  3: 2012-01-02 04:51:47 2012-01-04 03:47:44  d        3
  4: 2012-01-06 17:24:37 2012-01-06 23:12:37  g        5
  5: 2012-01-08 22:20:21 2012-01-09 09:12:45  f        9

我已經嘗試過以下方法:

test_function=function(date1="date1",date2="date2"){return(which(as.numeric((date1-date2))==as.numeric(min(date1-date2))))}
dat=dat[,test:=lapply(.SD,test_function), by =id, .SDcols = c("date1","date2")]

無濟於事。

理想的輸出將是這樣的(請注意,在此示例中,我彌補了行名2的值):

                   date1               date2 id row_name matching_row_name
  1: 2012-01-01 18:01:58 2012-01-02 06:36:13  b        1   32

或者,如果該范圍內沒有第二個日期,則

                   date1               date2 id row_name matching_row_name
  1: 2012-01-01 18:01:58 2012-01-02 06:36:13  b        1   NA

我做了幾個假設,因為問題中有些細節還不清楚。 由於沒有正的date1 - date2值,因此我選擇了date2 - date1 我也以分鍾為單位。 那么我的答案是:

f <- function(date1, date2) {
  dd <- as.numeric(difftime(date2, date1, units = 'days'))
  id <- which(dd > 0 & dd < 30)
  n <- length(id)
  if(n >= 1) which.min(dd)
  else if (n < 1) NA_integer_
}
dat[, matching_row_name := row_name[f(date1, date2)], by = id]

如有其他說明,我將更新答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM