2016-09-29 42 views
1

我想知道如何矢量化這段代碼。如何獲得不重疊的日期?

dates = list(as.Date(c("2000-02-08", "2000-02-11")), 
    as.Date(c("2000-03-02", "2000-03-07")), 
    as.Date(c("2000-03-02", "2000-03-07")), 
    as.Date(c("2000-03-03", "2000-03-07")), 
    as.Date(c("2000-03-16", "2000-03-30")), 
    as.Date(c("2000-03-16"))) 

i = 2 
while(i <= length(dates)) 
{ 
    if(dates[[i]][1] < dates[[i-1]][2]) 
    { 
     dates[[i]] = NULL 
     i = i-1 
    } 

    i = i+1 
} 

我想只得到那些不相交的日期。

Date1 = as.Date(c("2000-03-02", "2000-03-07")) 
Date2 = as.Date(c("2000-03-03", "2000-03-07")) 

例如,如果Date2包含在Date1範圍內,則我們刪除Date2。

+1

你可以看看'data.table'包中的'foverlaps'。 – Tensibai

+0

你輸出的例子聽起來不真實,日期確實相交(03之間,02和07 ..) – Tensibai

回答

1

隨着foverlaps從包data.table

dates = list(as.Date(c("2000-02-08", "2000-02-11")), 
      as.Date(c("2000-03-02", "2000-03-07")), 
      as.Date(c("2000-03-02", "2000-03-05")), 
      as.Date(c("2000-03-09", "2000-03-15")), 
      as.Date(c("2000-03-16", "2000-03-30")), 
      as.Date(c("2000-03-16"))) 

dt<-as.data.table(do.call(rbind,dates)) 
setkey(dt) 
# Get id of the ranges within others 
tmp <- foverlaps(dt,dt,which=T,type="within")[,xid] 
# summarize this 
t<-table(tmp) 

# Filter for ranges appearing only once, hence not included in another one. 
res <- dt[ as.integer(names(t[t==1])) , ] 
# not aboslutely necessary, but it's to retrieve date objects which were converted by the rbind call. 
res[, `:=`(V1=as.Date(V1,origin="1970-01-01"), V2=as.Date(V2, origin="1970-01-01"))][] 

輸出(如我加入例略有不同):

  V1   V2 
1: 2000-02-08 2000-02-11 
2: 2000-03-02 2000-03-07 
3: 2000-03-09 2000-03-15 
4: 2000-03-16 2000-03-30 

如果要排除任何相交,在設置type="any" foverlaps呼叫以獲得此輸出:

  V1   V2 
1: 2000-02-08 2000-02-11 
2: 2000-03-09 2000-03-15 
0

取決於你正在尋找什麼方向。在我的例子中,你看下面的任何數據行是否重疊(我只是看看開始日期,但你可以擴展它)。

dates = list(as.Date(c("2000-02-08", "2000-02-11")), 
      as.Date(c("2000-03-02", "2000-03-07")), 
      as.Date(c("2000-03-02", "2000-03-07")), 
      as.Date(c("2000-03-03", "2000-03-07")), 
      as.Date(c("2000-03-16", "2000-03-30")), 
      as.Date(c("2000-03-16"))) 

m <- do.call(rbind,dates) 

rem <- sapply(seq_along(m[,1]),function(x){any(which(
    m[x,1]<m[,2] & m[x,1]>=m[,1])>x)}) 

m[!rem,]