r data.frame回溯日期

时间:2016-07-07 23:30:11

标签: r date dataframe calendar rows

我有一个R data.frame如下。通过商店,我想创建newstart和newend列,以便newstart和newend将从相应的开始和结束列中减去14天。

但是如果newstart或newend日期在原始的开始或结束列中,那么我想再回到14天。

因此,在第3行的情况下,newstart和newend将分别为20131120和20131127。但是,由于20131120出现在商店8(第2行)的最后一栏,我必须再回去2周才能获得新手和新手。我必须再次检查以确保在开始和结束列中的商店8不存在newstart和newend。我怎么能这样做?

我有一个包含store列的多个值的表。我只是在这里展示快照

  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**

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

下面的第一个答案有效。但是在第二行和第三行以及最后两行的情况下,它提供重叠日期。如何确保newstart和newend中的日期不与开始和结束列重叠,以避免这种过度使用

{{1}}

1 个答案:

答案 0 :(得分:1)

您可以在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列中给定商店的冲突。也就是说,给定的商店可能具有重叠的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数据框中的行顺序,此方法可能会产生不同的结果,因为给定行中的新日期取决于先前行中的新日期。