とりあえず半歩

学んだことを1日1個、簡単なことでも良いから記録していきたい。

ggplot2の軸に日時データを用いつつ軸向きを逆にする

目標

ggplot2で、chronパッケージを使った日時データを軸に用いつつ、軸向きを逆にする。

動機

y軸に時間をとって、上から下に時間が流れるようなグラフが欲しいため。

chronパッケージ内にはscale_x_chron, scale_y_chronっていう軸をchron型に変数変換してくれる関数が 同梱されているのだけれど、scale_x_reverse, scale_y_reverse関数と一緒には使えない。

ちなみに、POSIXct型を用いてscale_x_reverse, scale_y_reverseを使うとエラーになる。

sample.dt <- data.table(datetime=as.POSIXct(c("2016-04-01 10:00:00",
                                              "2016-04-02 10:00:00",
                                              "2016-04-03 10:00:00",
                                              "2016-04-04 10:00:00",
                                              "2016-04-05 10:00:00")),
                        value=c(1,3,5,2,4))
g <- ggplot(sample.dt, aes(x=value, y=datetime)) +
  geom_path(size=1) +
  geom_point(size=3) +
  scale_y_reverse() +
  labs(title="Sample")
plot(g) ## Error in `-.POSIXt`(x) : unary '-' is not defined for "POSIXt" objects 

課題

chron型に変数変換しつつ、軸向きを逆にしてくれるscale_x_chron_reverse, scale_y_chron_reverse関数を作成する。

実施

環境

  • Windows 7 Home Premium 64bit
  • R 3.2.2
  • RStudio 0.99.489

作業

作った

2016.05.16 追記 --ここから--

以下のコードはchron, scalesのソースコードを参考にしているため、改変に当たりそうなのでライセンスを記載しました。

ライセンスはchronのものを引き継ぎ、GPL-2となります。 また、chronパッケージの著作権者の皆様は こちらです。

改変内容は次のとおりです。

  • scales::reverse_trans, chron::scale_x_chron, chron::scale_y_chronを参考にした以下の3関数の追加
    • chron_trans_reverse()
    • scale_x_chron_reverse()
    • scale_y_chron_reverse()

2016.05.16 追記 --ここまで--

chron_trans_reverse <- function(format="%Y-%m-%d", n=5) {
  transform. <- function(x) -as.numeric(x)
  inverse. <- function(x) chron(-x)
  breaks. <- function(x) chron((scales::pretty_breaks(n))(x))
  format. <- function(x) format(as.POSIXct(x, tz = "GMT"), format = format)
  scales::trans_new("chron_reverse",
                    transform=transform., inverse=inverse.,
                    breaks=breaks., format=format.)
}

scale_x_chron_reverse <- function(..., format="%Y-%m-%d", n=5) {
  ggplot2::scale_x_continuous(..., trans=chron_trans_reverse(format, n))
}

scale_y_chron_reverse <- function(..., format="%Y-%m-%d", n=5) {
  ggplot2::scale_y_continuous(..., trans=chron_trans_reverse(format, n))
}

結果

sample.dt2 <- data.table(datetime=chron(dates.=c("2016-04-01", "2016-04-02", "2016-04-03", "2016-04-04", "2016-04-05"),
                                        times.=rep("10:00:00", 5),
                                        format=c(dates="y-m-d",times="h:m:s")),
                         value=c(1,3,5,2,4))
g <- ggplot(sample.dt2, aes(x=value, y=datetime)) +
  geom_path(size=1) +
  geom_point(size=3) +
  scale_y_chron_reverse() +
  labs(title="Sample")
plot(g)

f:id:sotoattanito:20160506194553p:plain

説明

scales::reverse_transを参考に、scale_x_chron, scale_y_chronに少し手を入れただけ。

多分POSIXct型でも同じような感じで作れる気がするけれど、chronで満足してるのでとりあえずこれでよしとする。

もっと楽ちんな方法があればご教授ください。

参考

  • scake_x_chron, scale_y_chronのソース
  • scales::reverse_transのソース
  • trans_newのhelp