エクセルの日付(シリアル値)を、Rで使えるように変換する
例えば、セルの1つに「2014年7月22日」と入力してあったとしましょう。
これをXLConnectパッケージを使ってRで読み込むと、
> library(XLConnect)
> wb <- loadWorkbook("input.xlsx")
> ws <- readWorksheet(wb, sheet=1, header=F)
> ws
Col1
1 41842
のように、「2014年7月22日」と入力してあったセルの値が、「41842」となっています。
これはシリアル値といって、1900年1月1日を「1」、1月2日を「2」、・・・として日付を数値化したもので、エクセルは内部的にはこのように日付データを保持しています。というのを知っている人は多いと思います。
じゃあ、この値を日付としてRから使いたいときにどうやるのか? というのが今回のエントリの目的です。
Rには日付のシリアル表現のための関数があって、整数値と起源日付を指定することによって、シリアル値を日付(Date)型に変換することができます。
ということは、↓これでいけるはずだが・・・
> as.Date(41842, origin="1900-01-01") # 2014年7月22日のつもり
[1] "2014-07-24"
あれ? 2日ほどずれている。
このずれの原因の1つ目は以下のコードを実行することで、すぐに理解できます。
> as.Date(0, origin="1900-01-01")
[1] "1900-01-01"
> as.Date(1, origin="1900-01-01")
[1] "1900-01-02"
> as.Date(2, origin="1900-01-01")
[1] "1900-01-03"
エクセルでは1900年1月1日を「1」としているのに対し、Rのas.Date関数はoriginオプションで指定された日付(つまり1900年1月1日)を「0」としているわけですね。0オリジン vs 1オリジン のゴタゴタがこんなところにまで・・・
そして、ずれの原因の2つ目は、エクセルでシリアル値を実際に表示してみると判明します。
エクセル上でシリアル値を確認したい場合は、日付が入っているセルの書式設定で、表示形式タブを選択、ユーザー定義で「G/標準」を指定すればOKです。
絶対的な真理として、1900年はうるう年ではありません。つまり、1900年2月29日は存在せず、2月28日が59なら、3月1日を60にするべきなのです。なのに、そうなっていないせいで、1900年3月1日以降(あなたが扱うであろうほとんどの日付)に関しては、このずれが発生してしまうことになります。
このバグとも思えるような変な仕様は、(当時有力だった)「Lotus1-2-3」との互換性を維持するための意図的なものであったとのこと。
なんて、いきさつのことは知らなくても、やり方だけ覚えておけばOK。
【A】origin="1900-01-01"と指定するなら、シリアル値から2を引く または
というのでもいいけど、↓こっちの方がシンプルかも
【B】origin="1899-12-30"と指定する
【B】の方は、マニュアルにも書いてあって(?as.Dateと打てば見られます)、
## So for dates (post-1901) from Windows Excel
as.Date(35981, origin = "1899-12-30") # 1998-07-05
というサンプルが載っています。
マッキントッシュは起源日付が違うので、マック版エクセルでは、以下のようにすればいいらしいです。
## and Mac Excel
as.Date(34519, origin = "1904-01-01") # 1998-07-05
ウィンドウズ版: origin = "1899-12-30"
マック版 : origin = "1904-01-01"
というオプション指定だけを覚えてしまえば十分ですね。
これをXLConnectパッケージを使ってRで読み込むと、
> library(XLConnect)
> wb <- loadWorkbook("input.xlsx")
> ws <- readWorksheet(wb, sheet=1, header=F)
> ws
Col1
1 41842
のように、「2014年7月22日」と入力してあったセルの値が、「41842」となっています。
これはシリアル値といって、1900年1月1日を「1」、1月2日を「2」、・・・として日付を数値化したもので、エクセルは内部的にはこのように日付データを保持しています。というのを知っている人は多いと思います。
じゃあ、この値を日付としてRから使いたいときにどうやるのか? というのが今回のエントリの目的です。
Rには日付のシリアル表現のための関数があって、整数値と起源日付を指定することによって、シリアル値を日付(Date)型に変換することができます。
ということは、↓これでいけるはずだが・・・
> as.Date(41842, origin="1900-01-01") # 2014年7月22日のつもり
[1] "2014-07-24"
あれ? 2日ほどずれている。
このずれの原因の1つ目は以下のコードを実行することで、すぐに理解できます。
> as.Date(0, origin="1900-01-01")
[1] "1900-01-01"
> as.Date(1, origin="1900-01-01")
[1] "1900-01-02"
> as.Date(2, origin="1900-01-01")
[1] "1900-01-03"
エクセルでは1900年1月1日を「1」としているのに対し、Rのas.Date関数はoriginオプションで指定された日付(つまり1900年1月1日)を「0」としているわけですね。0オリジン vs 1オリジン のゴタゴタがこんなところにまで・・・
そして、ずれの原因の2つ目は、エクセルでシリアル値を実際に表示してみると判明します。
エクセル上でシリアル値を確認したい場合は、日付が入っているセルの書式設定で、表示形式タブを選択、ユーザー定義で「G/標準」を指定すればOKです。
絶対的な真理として、1900年はうるう年ではありません。つまり、1900年2月29日は存在せず、2月28日が59なら、3月1日を60にするべきなのです。なのに、そうなっていないせいで、1900年3月1日以降(あなたが扱うであろうほとんどの日付)に関しては、このずれが発生してしまうことになります。
このバグとも思えるような変な仕様は、(当時有力だった)「Lotus1-2-3」との互換性を維持するための意図的なものであったとのこと。
なんて、いきさつのことは知らなくても、やり方だけ覚えておけばOK。
【A】origin="1900-01-01"と指定するなら、シリアル値から2を引く または
というのでもいいけど、↓こっちの方がシンプルかも
【B】origin="1899-12-30"と指定する
【B】の方は、マニュアルにも書いてあって(?as.Dateと打てば見られます)、
## So for dates (post-1901) from Windows Excel
as.Date(35981, origin = "1899-12-30") # 1998-07-05
というサンプルが載っています。
マッキントッシュは起源日付が違うので、マック版エクセルでは、以下のようにすればいいらしいです。
## and Mac Excel
as.Date(34519, origin = "1904-01-01") # 1998-07-05
ウィンドウズ版: origin = "1899-12-30"
マック版 : origin = "1904-01-01"
というオプション指定だけを覚えてしまえば十分ですね。
コメント
コメントを投稿