cucumber flesh

Rを中心としたデータ分析・統計解析らへんの話題をしていくだけ

ハドリーに倣い、コンソールにブランチ名を表示&フォントを変える

何事も形から入るタイプの @u_ribo です。ネットストーキングに定評があります。

皆さんには憧れの人はいますか? 憧れの人が使っているものは、なぜか格好良く見えたり、自分も興味を抱くようになった経験はないでしょうか。

さて、憧れの人であるHadleyが登壇していた動画をYouTubeで見ていると気になる箇所がありました。この辺りです(次の動画の再生箇所)。

...プロンプト 1 にGitブランチ名を表示させるの格好いい

見た目重視の私は、憧れの人Hadley WickhamやRStudioチームが使っているものをすぐに真似したくなる癖があります。

調べてみると、どうもHadleyは自作関数でこの機能を実現可能にしていたようです。 そしてこの機能を含め、コンソールにさまざまな情報を表示させるのはpromptパッケージを使うと簡単に導入できることがわかりました。

github.com

MaraさんもTwitterで紹介されていました。

雰囲気はこのつぶやきのGif画像を見たらわかると思います。そんなわけで今回は実際に promptパッケージを使ってコンソールをカスタマイズする話です。

動機

コンソールに作業中のGitブランチ名を表示させたい理由は単に見た目が格好いいから、だけではありません。

時々、今どのブランチで作業しているのだっけ?となります。また、うっかりコミットするブランチを間違えたりもします。 そんな無駄やリスクを避けるためにブランチ名が見やすい位置に表示されているととても便利なわけです。

RStudioでもGit管理しているプロジェクトのブランチ名が表示されますが、常には表示されていません。複数あるタブの中からGitタブを選択した状態でない確認できません。GUI RやターミナルでRを実行する場合はこの機能もないので、ブランチの確認は別の方法頼みとなります。なので、コードを書いたり実行するコンソールに表示させておくと常にブランチを意識でき、上記の問題を回避可能です。

設定方法

利用するにはパッケージをインストールする必要があります。CRAN未登録なため開発版をGitHubから導入します。

install.packages("remotes")
remotes::install_github("gaborcsardi/prompt")
library(prompt)

promptには

  • prompt_*() で見た目の確認
  • set_prompt()prompt_*()の内容を反映させる
  • suspend(), restore(), toggle() で元に戻す

の機能があります。

Gitブランチ名の出力の他、実行したコードのステータス、起動中のRプロセスにおけるメモリ分配量の表示が可能です。

f:id:u_ribo:20191215095220j:plain

上記の画像は prompt_fancy を指定したターミナルでのRの画面です。オシャレですねー。

では本題、Gitブランチ名の表示を反映させましょう。コンソールで次のコマンドを実行します。なおGitバージョン管理をしていないプロジェクトないし作業ディレクトリでは通常のプロンプトが表示されます。

set_prompt(value = prompt_git)

もちろんmaster以外であればそのブランチ名になります。さらにGitでバージョン管理しているファイルに変更がある状態だとブランチ名の最後に * がつきます。

最後に、この設定はRを終了するとなくなってしまうので、起動時に実行されるよう.Rprofileに書き込んでおきましょう。.Rprofileの編集はusethis::edit_r_profile()を使うのが簡単です。

私の設定は次のようになっています。

.First <- function() {
  if (interactive()) {
    prompt::set_prompt(value = prompt::prompt_git)
  }
}

おまけ: 視認性の高いhackフォントへの変更

Hadleyが登壇している動画を見ていると、彼のRStudio画面で使われているフォントに目が行きます。探してみると、Hadleyは2015年からこのフォントを使っているみたいです(今更気づいてしまった)。

Hack、名前がいいですね。こちらもサクッと真似しましょう。

github.com

f:id:u_ribo:20191215095240p:plain

Hackに設定したRStudioのキャプチャ画面です。0とO、lと1など、見分けづらい文字の視認性が上がっているように思います。

RStudioではエディタやコンソールで表示されるフォントを好みのものに変更できるので、ぜひ気に入ったものを使ってください。 フォントをダウンロード・インストールしたら環境設定を開き、AppearanceのEditor Fontに指定するだけです。 良さげなフォントについては https://blog.nakanishy.com/programming-fonts.html が参考となりました。

ちなみに、これまでは合字に対応したFireCodeInconsolataを使っていました。

Enjoy!


  1. システムが入力を待っている状態の時に表示される文字や記号です。Rではデフォルトで > がプロンプトとして使われます。

ggplot2の凡例を制御するためのオプション show.legend

ggplot2の凡例に関する小話を2つ。べ、別に最近知ったわけじゃないんだからね!

geom_*(show.legend = FALSE) で凡例を非表示にする

ggplot2での作図で凡例を制御する関数として guides()があります。この関数内でグラフに使われる凡例のタイトルや並びを調整可能です。例えば、irisデータセットのSpeciesごとに色分けをした図の凡例の並びを入れ替えるには次のようにします。guides(color = guide_legend(reverse = TRUE)) がその処理を指定している箇所です。

library(magrittr)
library(ggplot2)
library(patchwork)
theme_set(theme_gray(base_size = 12, base_family = "IPAexGothic"))
p <-
  iris %>% 
  ggplot(aes(Species, Sepal.Length, color = Species)) +
  geom_boxplot()

p1 <- 
  p +
  ggtitle("color = Speciesを指定した時のデフォルト")
p2 <- 
  p +
  guides(color = guide_legend(reverse = TRUE)) +
  ggtitle("guides()で凡例の並びを変更")
p1 + p2 + plot_layout(ncol = 2)

f:id:u_ribo:20191212065732p:plain

この関数を利用して凡例を非表示にできます。あるいは guides() を使わず theme(legend.position = "none") でも良いです。

# 出力結果は省略
p +
  guides(color = FALSE)

一方で、凡例を非表示にするためにこの方法を利用すると、一つ使う関数が増えてしまいますし、関数内で指定する引数の値をうっかり忘れてしまうことがあります。私はよく、color = NULL とか color = NA と間違った指定をしてしまっていました。

そこで、表示しない凡例については、どの種類の図を描画するかを定義する geom_*()を実行する段階で指定できる show.legend 引数を使うと便利です。例えば先ほどの箱ひげ図、X軸のラベルとしてSpeciesが与えられているので凡例は消そうと思うと次のようにします。

# 出力結果は省略
iris %>% 
  ggplot(aes(Species, Sepal.Length, color = Species)) +
  geom_boxplot(show.legend = FALSE)

この引数オプション、最近実装された訳ではなく、昔からあります。ドキュメントにもしっかり書かれています(既定値はNA)。便利な機能はすでに用意されている…そういう気持ちでドキュメントを読み込んでいきたいと思いましたまる

sfオブジェクトの凡例を変更する

2019-01-12追記 id:yutannihilation さんのタレコミによると ggplot2 v3.3.0 からはgeometryの種類の判別が自動的に行われるようになるそうです。

notchained.hatenablog.com

ggplot2の凡例についてもう一つ。次は地理空間データを描画する際に利用する geom_sf() での話です。

geom_sf()でなんらかの凡例を表示させた際、デフォルトでは fill を指定した時のように四角形の枠が表示されます。

library(sf)
sf_nc <- 
  system.file("shape/nc.shp", package = "sf") %>% 
  st_read() %>% 
  .[seq.int(3), ]
ggplot() + 
  geom_sf(data = sf_nc, aes(fill = NAME))

f:id:u_ribo:20191212070124p:plain

対象の地物がポリゴンだと良いですがポイントやラインのデータだとモヤっとした気持ちになります。こうした凡例の種類を調整するのにも先ほどの show.legend が使えます。凡例の種類を枠ではなく点にしたいのであれば show.legend = "point" を与えます。

sf_point$size <- 
  as.character(sample(10))

p1 <- 
  ggplot() +
  geom_sf(data = sf_point, aes(color = size)) +
  ggtitle("geom_sf()のデフォルト")

p2 <- 
  ggplot() +
  geom_sf(data = sf_point, aes(color = size), 
          show.legend = "point") +
  ggtitle("show.legend = で凡例の種類を変更")

p1 + p2 + plot_layout(ncol = 2)

f:id:u_ribo:20191212070531p:plain

よかったですね。

また、この場合の凡例としては不適切ですが、 "line" を指定して線の凡例を得も得られます。

# 出力結果は省略
ggplot() +
  geom_sf(data = sf_point, aes(color = size), 
          show.legend = "line")

Enjoy!

標準的な公共交通機関の情報形式 GTFS をRで処理する: gtfsrouter編

f:id:u_ribo:20191117103306j:plain

この記事はRアドベントカレンダー2019の5日目の投稿です。昨日は id:ando_Roid さんの投稿でした。

はじめに

今回で4回目となる「東京公共交通オープンデータチャレンジ」の応募が始まりました。これは公共交通オープンデータやその他のオープンデータを活用したアプリケーションおよびサービスの提案に関するコンテストです。ここでは、鉄道、バス、航空などの交通機関のデータが、GTFS (General Transit Feed Specification) 形式で公開されています。

GTFSは公共交通機関の時刻表と地理的情報に関するオープンフォーマットとして定義されます。リアルタイムの運行情報を反映した動的データ (GTFS Realtime)と、ダイヤ改正等の事情がない限り安定した静的データがあり、GTFSといえば厳密には静的データの方を指します。複数の事業者・交通機関が共通の形式に従ってデータを整備することで、経路探索や時刻表のアプリケーション開発が容易になるのが利点です。そのため、GTFSを提案したGoogle以外でも広く使われています。日本の交通機関に関しても、GTFSをベースに日本独自の交通事情を加味しながら拡張されたフォーマット (GTFS-JP) が整備されています。

さて、今回はそんなGTFSをRで扱ってみようという記事になります。日本語の内容として id:nonki1974 さんがgtfsrパッケージの利用方法を スライドにまとめています。なのでここでは、もう一つの例として gtfsrouterパッケージを紹介します。

目次です。

  • はじめに
  • gtfsrouterパッケージ
    • デモデータの処理
    • data.tableによるGTFSデータの操作
  • RでGTFSデータを扱う際のTips
    • 連続値になっている時刻の変換
    • sfオブジェクトへの変換

gtfsrouterパッケージ

github.com

gtfsrouterパッケージの特徴として次の点が挙げられます。

  • 2019年12月5日現在、CRANに登録されている。gtfsrは未登録
    • ただし、現在はGitHub上の開発版を利用するのが良さそう (issue #14 参照)
  • GTFSデータをdata.tableオブジェクトとして処理するため、処理速度の高速化が期待できる
  • 指定時間内に移動可能な領域 (Isochrone map) の描画ができる

まずはパッケージを利用可能な状態にしておきます。CRANに登録されているバージョンではなくGitHub上の開発版をインストールします。

install.packages("remotes")
remotes::install_github("ATFutures/gtfs-router")
# gtfs_isochrone()を実行する際に必要です
# install.packages(c("alphahull", "geodist"))
続きを読む