2017-01-19 11 views
1

私は3列の日付を持っています。日付の再編成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 

私は以下の位置に並べ替えたいと思います。何が起こるかは、私が行を取ることです。値は前の行の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)) 

しかし、これは常に行の最初の項目のための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

dplyr::coalesceを試してみてください。これは、成分ごとの引数の中で最初の非NA値を返します。

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

: `coalesce`機能について

  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 
+0

おかげで、あなたは' coalesce'対の実行時間の比較を含めることができますベクトルの計算、すなわち、 'conditionVal = as.Date(ifelse(!is.na(lag(test $ c))、lag(test $ c)、lag(test $ b)));テスト$ a = as.Date(ifelse(is.na(conditionVal)、test $ a、conditionVal)) ' – OdeToMyFiddle

+0

ありがとうございました。 – ogiz

+0

@ogiz、解決策が満足であれば、左側のをクリックしてそれを受け入れることができます – OdeToMyFiddle