2016-07-07 54 views
0

我有一個R data.frame如下。通過商店,我希望創建新的和新的列,以便從相應的開始和結束列中減去14天的新開始時間和新結束時間。r data.frame回去日期

但是,如果新的開始或新的日期是在原始的開始或結束列,那麼我想回14天進一步。

所以在第三排的情況下,newstart和newend分別是20131120和20131127。但是,20131120出現在商店8(第2行)的最後一列,我必須再返回2個星期才能獲得新手和新手。我必須再次檢查以確保在開始和結束列中的商店8不存在新開始和新開始。我怎麼能這樣做?

我有一個包含多個存儲列值的表。我只是顯示一個快照這裏

store=c(rep(8,4),rep(11,4)) 
start=c("20131009","20131113","20131204","20150624","20140820","20140924","20150923","20151014") 
end=c("20131016","20131120","20131211","20150701","20140827","20141001","20150930","20151021") 

maint=data.frame(store,start,end) 



maint$start=as.Date(maint$start,"%Y%m%d") 
maint$end=as.Date(maint$end,"%Y%m%d") 
maint 
    store start  end 
1  8 20131009 20131016 
2  8 20131113 20131120 
3  8 20131204 20131211 
4  8 20150624 20150701 
5 11 20140820 20140827 
6 11 20140924 20141001 
7 11 20150923 20150930 
8 11 20151014 20151021 

---------------------- UPDATE1

下面的作品第一次的答案。但是在第二行和第三行以及最後兩行的情況下,它會提供重疊的日期。我怎樣才能避免這種overalap同時確保在NEWSTART和newend日期不具有起點和終點柱

store start end newstart newend 

8 10/9/2013 10/16/2013 9/25/2013 10/2/2013 
**8 11/13/2013 11/20/2013 10/30/2013 11/6/2013 
8 12/4/2013 12/11/2013 10/23/2013 10/30/2013** 
8 6/24/2015 7/1/2015 6/10/2015 6/17/2015 
11 8/20/2014 8/27/2014 8/6/2014 8/13/2014 
11 9/24/2014 10/1/2014 9/10/2014 9/17/2014 
**11 9/23/2015 9/30/2015 9/9/2015 9/16/2015 
11 10/14/2015 10/21/2015 9/2/2015 9/9/2015** 

回答

1

你可以使用一個while循環中的for循環如下

# create newdate columns 
maint$newstart <- as.Date(NA) 
maint$newend <- as.Date(NA) 

# loop over each row of maint 
for(i in 1:nrow(maint)) { 

    # get all start and end dates for current store 
    dates_focal <- c(maint$start[maint$store == maint$store[i]], 
        maint$end[maint$store == maint$store[i]]) 

    # subtract 14 days from newstart and newend 
    newstart <- maint$start[i] - 14 
    newend <- maint$end[i] - 14 

    # exit condition for following while loop 
    exit_condition <- F 

    # check for conflict 
    # if conflict, repeatedly subtract 14 days until no more conflict 
    while(!exit_condition) { 

    conflict <- any(is.element(c(newstart, newend), dates_focal)) 

    if (conflict) { 
     newstart <- newstart - 14 
     newend <- newend - 14 
    } else { 
     exit_condition <- T 
    } 
    } 

    # set newstart and newend 
    maint$newstart[i] <- as.Date(newstart) 
    maint$newend[i] <- as.Date(newend) 
} 

注意重疊的這個例子不檢查newstart和newend列中給定商店的衝突。也就是說,一個給定的商店可能有重疊的新開始日期和新的日期(在不同的行中)。如果這對您的應用程序不合適,應該進行快速修改。

更新1

如果你還需要檢查衝突的NEWSTART和newend列,只是這些列添加到dates_focal,如:

dates_focal <- c(
    maint$start[maint$store == maint$store[i]], 
    maint$end[maint$store == maint$store[i]], 
    maint$newstart[maint$store == maint$store[i]], 
    maint$newend[maint$store == maint$store[i]] 
) 

請記住,這種方法可能會產生不同結果如果您的maint數據框中的行順序發生更改,因爲給定行中的新日期取決於先前行中的新日期。

+0

感謝您的回答和您的評論。是否有可能回答我的更新1,這與您提到的相同... – user2543622