r data.frame 回溯日期
r data.frame going back dates
我有一个 R data.frame 如下。通过商店,我想创建 newstart 和 newend 列,这样 newstart 和 newend 将从各自的开始和结束列中减去 14 天。
但是,如果新开始或新结束日期在原始开始或结束列中,那么我想再往后回溯 14 天。
因此在第 3 行的情况下,newstart 和 newend 将分别为 20131120 和 20131127。但是由于 20131120 出现在商店 8(第 2 行)的末尾列中,我必须再返回 2 周才能获得 newend 和 newstart。我必须再次检查以确保开始和结束列中的商店 8 不存在 newstart 和 newend。我怎么能这样做?
我有一个 table 存储列有多个值。我只是在这里展示一个快照
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
--------------------更新1
下面的第一个答案有效。但是在第二行和第三行以及最后两行的情况下,它提供了重叠的日期。我如何在确保 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**
您可以在 for 循环中使用 while 循环,如下所示
# 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]]
)
请记住,如果更改维护数据框中的行顺序,此方法可能会产生不同的结果,因为给定行中的新日期取决于之前行中的新日期。
我有一个 R data.frame 如下。通过商店,我想创建 newstart 和 newend 列,这样 newstart 和 newend 将从各自的开始和结束列中减去 14 天。
但是,如果新开始或新结束日期在原始开始或结束列中,那么我想再往后回溯 14 天。
因此在第 3 行的情况下,newstart 和 newend 将分别为 20131120 和 20131127。但是由于 20131120 出现在商店 8(第 2 行)的末尾列中,我必须再返回 2 周才能获得 newend 和 newstart。我必须再次检查以确保开始和结束列中的商店 8 不存在 newstart 和 newend。我怎么能这样做?
我有一个 table 存储列有多个值。我只是在这里展示一个快照
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
--------------------更新1
下面的第一个答案有效。但是在第二行和第三行以及最后两行的情况下,它提供了重叠的日期。我如何在确保 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**
您可以在 for 循环中使用 while 循环,如下所示
# 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]]
)
请记住,如果更改维护数据框中的行顺序,此方法可能会产生不同的结果,因为给定行中的新日期取决于之前行中的新日期。