2012-03-05 24 views
3

これは、はるかに簡単にする必要があり、誰かが私を助けることができるようです。私は、それぞれの月の最初の日付を、rubridateパッケージのfloor_date()を使って日付のdata.frameから変更しようとしていますが、それらの日付のいくつかはNAです。私はむしろNAにダミーの日付を代用することはしません。Rの日付を変換してNAの日付を変換するのに適用する

私は以下試してみた:

library(lubridate) 
a<-c(as.Date("2011-05-04"), as.Date("2011-06-12")) 
b<-c(as.Date("2012-03-01"), NA) 
test <- data.frame(a,b) 

apply(test, 1, function(y) sapply(y, function(x) if(!is.na(x)) floor_date(x, "month") else na.pass(x))) 
apply(test, 1, function(y) ifelse(!is.na(y)), floor_date(y, "month"), na.pass(y)) 

最初の呼び出しが戻る:

Error in object[[name, exact = TRUE]] : subscript out of bounds 

二コール・リターンを:

Error in update.default(x, mdays = 1, hours = 0, minutes = 0, seconds = 0) : 
need an object with call component 

は、任意の助けをありがとう!

+1

大きな問題は、 'apply'が行列を強要しようとしていて、R" Date "を日付にすることを含むすべての属性が失われるということです。' lapply'をonにする必要があります列を処理するのではなく、列を使用することをお勧めします –

+0

各日付を最初の月に変換したいのですか?そうであれば、一度に1つずつ行を処理することは意味を持ちません。 、1、....) 'します。あなたはむしろ' data.frame(lapply(test、...)) 'のようなことをする必要があります。これは' test'の各列を取り、それらの計算を実行しますそれぞれの順番に並べ替えて、結果の列のリストをdata.frameに戻します。 –

答えて

7

私がlubridateについて知らないが、あなたは基本R.が提供する優れた日付取り扱う施設で簡単にこれを行うことができます

ここで文句なしにしたい計算を実行しなければならない小さなヘルパー関数です:

firstOfMonth <- function(dates) { 
    as.Date(strftime(dates, format="%Y-%m-01")) 
} 

firstOfMonth(a) 
# [1] "2011-05-01" "2011-06-01" 
firstOfMonth(b) 
# [1] "2012-03-01" NA 

data.frame(lapply(test, firstOfMonth)) 
#   a   b 
# 1 2011-05-01 2012-03-01 
# 2 2011-06-01  <NA> 
+0

doh!私は、複雑すぎることを知っていました!ありがとうございました。この試験のDateクラスオブジェクトの代わりにベクトルプレ – tcash21

+0

また、lubridateの 'floor_date()'は単に 'NA'を扱うように設計されていないように見えるので、自分のコードなどを使うほうが良いでしょう。 (あなたのベクトル 'b'で' floor_date(b) 'を試して、私の意味を見てください)。 –

1

これはいかがですか?

my_floor_date <- function(x,...) {idx <- !is.na(x); x[idx] <- floor_date(x[idx], ...); x} 
transform(test, a=my_floor_date(a, "month"), b=my_floor_date(b, "month")) 
2

パッケージ動物園を試しましたか?

library(zoo) 
a<-c(as.Date("2011-05-04"), as.Date("2011-06-12")) 
b<-c(as.Date("2012-03-01"), NA) 
test <- data.frame(
     "a" = as.Date(as.yearmon(a)), 
     "b" = as.Date(as.yearmon(b)) 
) 
1

あなたがしようとしていたようにワンライナーでそれをやってみたかった場合、これは動作します:

data.frame(lapply(test,function (y) (as.Date(sapply(y,function(x) if (is.na(x)) NA else floor_date(x,'month')))))) 

ここでの本当の問題はあなたが合格できるようにする必要がありlubridate機能そのものであり、 NAを無視するように指示するパラメータupdate.Date。上記のstrftimeソリューションは間違いなく最もクリーンです。

また、コメントに記載されているように、lapplyの代わりにapplyを使用したため、ソリューションが機能しなかった理由がありました。

1

floor_date()のNAバグは、今日CRANに送信されたlubridate 1.1.0で修正されています。日付のS3更新メソッドのNAバグが残っています(開発版で修正済み)。その間、

floor_date(as.POSIXlt(test$b), unit = "month") 

となります。