ill-identified diary

所属組織の見解などとは一切関係なく小難しい話しかしません

[メモ] RStudio 1.4 時点での Python 関係トラブルシュートとか

この記事は最終更新日から3年以上が経過しています

概要

先日リリースされた RStudio 1.4.1103 の新機能として, Python 実行環境のサポートが強化されたことが挙げられる*1. たとえば R と同様の環境ペーンが使えるようになったため, グローバルのオブジェクトやロード中のモジュールの一覧を確認しやすくなった. これは対話的に実行するときにとても便利である. しかし Python まわりにはまだ変な不具合がいくつか残っているので解決/回避方法含めて脈絡なく挙げていく.

これまでに見つけた不具合

Windows は英語ロケールでないと対話モード不可?

問題の詳細

  • 発生するOS: Windows 10 (それ以前は不明)

多分RとPython少なくともどちらか片方の初心者が見ることが多いと思うので一応「対話モード (REPL)」がなんなのか説明しておくと, 随時実行できるやつ. たとえば RStudio で “Python script” を新規作成すると, 書いたコードを Ctrl + Enter などで随時実行できる. 一見なにも設定しなくてもできるようにみえるが, よく見ると reticulate パッケージの対話モード実行機能が呼び出されている (図1).

図 1: RStudio の Python 対話モード
f:id:ill-identified:20210222230445p:plain

その後 Console に直接コードを書いて実行するのも「対話モード」. この時呼び出される R の関数 reticulate::repl_python()Python の対話モードを制御している. ここで私は「対話モード」と呼んでいるが, 公式には Python REPL (read-evaluate-print loop) と呼ばれる.

R-wakalang で先日話題になった*2のは, Windows 10 で Python を対話モードで実行する際に使うこの repl_python() が呼び出された瞬間に RStudio がクラッシュするというもの. これはおそらく R 本体, Python 本体, そして reticulate パッケージのバージョンに関係なく起こる. 本件に対する対応方法は既にスタック・オーバーフロー日本語版に投稿してあるが, 今一度原因と対策をまとめる.

解決法

問題の発生する条件は, issue #8285, 8549 を見るに, (1) Windows 10 の使用, (2) 言語設定を日本語 (韓国語でも問題が報告されているので, 非ラテン文字言語全般が対象かもしれない) にする, (3) RStudio 1.4.1103, (4) repl_python() を呼ぶ, という条件を全て満たすときにであるので, 以下のようにいくつか回避方法がある. 掲載順はオススメ順.

  1. RStudio を Daily Build 1.4.1533 以降のものにアップデートする

    • Daily Build はいわゆる正式リリース版ではないので, 不安なら RStudio を 1.3 に戻すことで妥協することも可 (Python 関係の便利な新機能が使えなくなるが)

  2. repl_python 以外の方法で Python コードを実行する (対話的に実行せずに Rmd のチャンクに書いて knit する, スクリプトファイルとして呼び出す, など)

    • 対話的に実行できないため, RStudio を VS Code や Pycharm など, あるいは Jupyter の代わりに使いたいという人には不満が残る対策だろう. Rmd でもチャンクごとに実行しようとすると repl_python() が呼び出されるため knit ボタンによる一括実行しかできない.

  3. Windows 以外の OS を使う

    • Windows 上で Linux の仮想環境を使う, あるいは 非 Windows OS サーバ上で RStudio Server を動かすことで回避できるかは未検証

  4. Windows の言語設定を English にする

    • もちろん表示が全て英語になる.

    • キーボード配列も変わってしまうのでそちらも設定が必要

matplotlib で画像のプロットができない

問題の詳細

  • 関係する OS: たぶん Windows のみ

  • 関係する Python 環境: miniconda

miniconda で Python 環境を構築した (install_miniconda()) 場合, 例えば以下のようにして matplotlib (おそらく他の派生モジュールでも) でプロットしようとする.

plt <- import('matplotlib.pyplot')
plt$plot(1)

すると, ヘッダファイルが見つからないどうこうのエラーログが大量に現れその直後, RStudio がクラッシュする. これは reticulate パッケージ (ver. 1.18 時点) の不具合のようだ.

解決法

reticulate ver. 1.18 の不具合は開発版ではすでに修正されている*3ので, remotes::install_github(rstudio/reticulate) で最新の開発版をインストール.

もしくは reticulate をアップデートしなくとも, RStudio の 1.4.1533 以降でもこのエラーが発生しなくなった. (原因はよくわからない)

pyenv の Python が認識されない

  • 関係する Python 環境: pyenv を使用している, または複数のバージョンの Python を (conda 系や virutalenv 等の管理ツールを使わず) インストールしている場合

問題の概要

これは不具合とは少し違う. pyenv を使おうとしてうまく動作しない場合, あるいはすでにインストールしたつもりのはずのモジュールをインポートしようとしたらなぜか見つからない, と言われたときは, RStudio 側が異なる Python 環境 (よくあるパターンは 2.x と 3.x を両方入れている場合) を認識している可能性がある.

解決法

まずは py_config() で RStudio 側が実際にどの Python を認識しているかを確認.

pyenv を使っていてて, py_config() の出力の “libpython:” の欄が空白になっているならだいたい共有ライブラリのインストールを忘れている. pyenv はデフォルトで共有ライブラリをインストールしないが, reticulate はこれを要求するため Python を実行できなくなるというのが理由. これの解決法は以前書いたとおり*4.

それ以外の場合, reticulate パッケージには一定のルールでマシンの Python 環境を検索しているので, py_config() の “python:” のファイルパスがいつも使っているものと違うのなら, 設定を変える必要がある. pyenv に限らず, 複数の Python 環境をインストールしている場合, reticulate パッケージは自身を読み込んだ時点でどの Python を使うか決めてしまうので, 読み込み前に環境変数を設定する必要がある.

例えば conda や pyenv, virtualenv などを使わず Python の公式インストーラから直接 Python 3.9 をインストールした場合は, インストールディレクトリを見つけて*5, reticulate パッケージの読み込み前に以下のように書いて実行する (ネット上では Windows での用例が少なかったので Windows のデフォルトのインストールフォルダにしてみた).

Sys.setenv(RETICULATE_PYTHON = "~/AppData/Local/Python39/Python/python.exe")

pyenv 以外のものが優先されてしまう場合も, この環境変数を設定するとよいだろう. 毎回書くのは面倒なので .Rprofile とかに書いてもいい.

どの Python を使うかのルールは公式の https://rstudio.github.io/reticulate/articles/versions.html の “Order of Discovery” に言及がある. 以下はそこに書いてあることそのまま.

  1. RETICULATE_PYTHON 環境変数をもとに Python 実行ファイルを検索する

  2. (reticulate 読み込み後に) use_python(), use_virtualenv(), use_condaenv() などで指定されたもの

  3. 最初に import で指定されたされたモジュール名. たとえば import(nltk) を最初に実行したなら, ユーザーディレクトリの以下の場所が検索される

    • 〈現在の作業ディレクトリ〉/nltk

    • ~/.virtualenvs/nltk

    • ~/anaconda/envs/nltk

    • ~/nltk

このあたりの挙動はここ2, 3年の間に書かれた日本語の記事とまたちょっと変わってる気もするので, なるべく公式サイトを見たほうが良いだろう (公式もそこまで説明が充実していないような気がするが).

notebook でコードの実行結果が表示されない?

  • 関係する Rmd フォーマット html_notebook

これはついさっき R-wakalang に投稿されたもの. おそらく RStudio 1.4 特有のバグではなく質問者の思い違いが原因だと思われるが, ちょっとググった限りでは, 日本語で R notebook のこの仕様に言及しているページは見つからなかったのでついでに書いておく.

html_notebookhtml_document と似ているが, 別物として扱われる. 特に気をつけなければならない両者の違いは, notebook は document と違って preview ボタンを押してもチャンクが実行されない*6. document その他のフォーマットは knit ボタンで (キャッシュ設定を変更していないなら) 全てのコードチャンクが実行されるが, notebook を使っていると現れる “preview” というボタンの表示はコードチャンクが実行されないことを表す. Rmd ファイルのエディタ内でチャンクを実行したものが preview に反映される. さらに, document とはキャッシュを共有していないので, document を knit したからと言って notebook に反映されることもない.

ここにない不具合に出くわしたあなたへ

Python や R にまだ詳しくない人向けに, ヒントを教える. まずは RStudio, Python, reticulate パッケージ, どれが原因で不具合が発生しているのかを突き止めるとだいぶ対策しやすくなる. たとえば, 冒頭の 「Rstudio 1.4 で Python がクラッシュする」という不具合は RStudio を使わず, R コンソールで reticulate::repl_python()を呼び出しても発生しない. よって RStudio の不具合の可能性が高いと推理できる. コンソールでもエラーが出るなら reticulate パッケージの問題かも知れないが, Python 側に問題の可能性も残っている. つまり, Python 単体で同じコード実行をすることはできるか, である. Python を R を経由せず実行できるが, R 経由ではできないというのなら reticulate が原因の可能性が高いが, そうでないなら Python のインストールがうまくいってないだけかもしれない (ただし Python 環境を複数インストールしている場合は reticulate と同じ環境を使っているか注意しなければならない).