重新排列日期r

时间:2017-01-19 12:10:52

标签: r

我有三列日期。

test <- data.frame(a = as.Date(rep("2008-02-04", 5)),
               b = as.Date(c("2010-01-25",
                             "2012-04-13",
                             "2013-04-04",
                             "2013-09-06",
                             "2014-08-14")),
               c = as.Date(c("2010-01-29",
                             "2012-04-16",
                             NA,
                             "2013-09-19",
                             "2014-08-21"))); test
           a          b          c
1 2008-02-04 2010-01-25 2010-01-29
2 2008-02-04 2012-04-13 2012-04-16
3 2008-02-04 2013-04-04       <NA>
4 2008-02-04 2013-09-06 2013-09-19
5 2008-02-04 2014-08-14 2014-08-21

我想在以下位置重新安排它们。会发生的是我将行A值替换为前一行的C值。并且如果前一行C是NA,则取上一行B的值并将其置于当前a。

           a          b          c
1 2008-02-04 2010-01-25 2010-01-29
2 2010-01-29 2012-04-13 2012-04-16
3 2012-04-16 2013-04-04       <NA>
4 2013-04-04 2013-09-06 2013-09-19
5 2013-09-19 2014-08-14 2014-08-21

到目前为止,我已经用for循环解决了这个问题:

n <- nrow(test)
if (n > 1) {
  for (i in 1:(n - 1)) {
    empty <- is.na(test$c[i])
    if (empty)
      test$a[i + 1] <- test$b[i]
    else
      test$a[i + 1] <- test$c[i]
  }
}

我想通过使用dplyr包知道是否有更快的方法来做到这一点。我想在ifelse语句中使用mutate,但我不知道如何为我想要改变的变量选择i + 1。我试着做以下事情:

test %>% mutate(a = if_else(is.na(lag(c, n = 1)),
                            true = lag(b, n = 1),
                            false = lag(c, n = 1),
                            missing = a))

但是这总是为第a行中的第一项返回NA:

           a          b          c
1       <NA> 2010-01-25 2010-01-29
2 2010-01-29 2012-04-13 2012-04-16
3 2012-04-16 2013-04-04       <NA>
4 2013-04-04 2013-09-06 2013-09-19
5 2013-09-19 2014-08-14 2014-08-21

1 个答案:

答案 0 :(得分:1)

试试dplyr::coalesce。它在组件方面的参数中返回第一个非NA值:

test %>% mutate(a = coalesce(lag(c), lag(b), a))

,并提供:

           a          b          c
1 2008-02-04 2010-01-25 2010-01-29
2 2010-01-29 2012-04-13 2012-04-16
3 2012-04-16 2013-04-04       <NA>
4 2013-04-04 2013-09-06 2013-09-19
5 2013-09-19 2014-08-14 2014-08-21