自前の R パッケージを Azure Synapse Analytics Apache Spark プール のワークスペースパッケージとして使用する

本記事執筆時点ではパブリックプレビューですが、 [Azure Synapse Analytics](https://learn.microsoft.com/azure/synapse-analytics/) の [Apache Spark プール](https://learn.microsoft.com/azure/synapse-analytics/spark/apache-spark-pool-configurations) では Python (PySpark), Scala, C# (.NET Spark), SQL だけでなく、[R言語](https://www.r-project.org/) ([SparkR](https://spark.apache.org/docs/latest/sparkr.html)) も使用することができます。Apache Spark のバージョンとしては 3 以上で利用でき、本記事執筆時点で利用可能なバージョンは 3.1, 3.2, 3.3 (プレビュー) の 3 種類です。

Apache Spark プールで R のパッケージを利用する方法は 2 通りです。

1. [ノートブック セッション パッケージ](https://learn.microsoft.com/azure/synapse-analytics/spark/apache-spark-manage-session-packages)
2. [ワークスペース パッケージ](https://learn.microsoft.com/azure/synapse-analytics/spark/apache-spark-manage-workspace-packages)

前者の方が一時的なもので、後者の方が恒久的なものです。

なお、Python の場合は上記以外に [Spark プール パッケージ](https://learn.microsoft.com/azure/synapse-analytics/spark/apache-spark-manage-pool-packages) という方法もあり、上記の中だと中間に位置します。

ノートブック セッション パッケージ の方が簡単です。ノートブックのセル内で

```r
install.packages("パッケージ名")
```

と実行すれば、[CRAN](https://cran.r-project.org/mirrors.html) (Comprehensive R Archive Network) から依存関係も含めてパッケージをダウンロードし、コンパイル等してインストールしてくれます。フィーリングとしては [Gentoo Linux](https://ja.wikipedia.org/wiki/Gentoo_Linux) の [Portage](https://ja.wikipedia.org/wiki/Portage) に似ていると思います。また、上記以外にも `devtools` が利用可能です。

ただ、ノートブック セッション パッケージ はお手軽である反面、Spark のセッションが終了したらインストールしたパッケージも消えてしまうのがデメリットです。CRAN からのインストールの際にアーキテクチャに合ったバイナリをインストールしてくれれば早いのですが、そうではなく逐一コンパイルをするため、R パッケージのインストールには時間がかかります。

一方、ワークスペース パッケージ を利用すれば、Spark のセッションが終了しても、Spark クラスターにパッケージがインストールされたままとなります。こちらの方が良さそうに見えますが、デメリットとしては、依存関係が解決されないことです。

本記事では、前提となる環境構築手順を示した上で、R をワークスペース パッケージ として利用する際の失敗例と、問題の解決方法を示します。長くなるので、最初から解決方法を見ていただいても構いません。
なお、サンプルとして利用する R パッケージは [C50](https://cran.r-project.org/web/packages/C50/index.html) とします。


## 環境構築

Apache Spark プールにクラスターを作成します。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/f8617e4d-e379-eb74-a11e-1f41ef87638c.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/7db0168c-787b-dcab-140b-dc4f3d381347.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/e14f39e9-2bb0-7d0e-38b1-b198850830ed.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/e3ceed60-73c5-33a7-61da-2b849d5656cd.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/e356b7d5-ccfc-78bd-a47d-dce7acbfbcb1.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/055a71f5-26d0-1f90-a575-ed80abd7d97f.png)


## 失敗例

まず、ワークスペース パッケージに C50 を登録します。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/05ac2f5a-4f85-16cc-865b-0ab419093c25.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/4962f221-7c6a-392e-0708-3744d794ba36.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/b65b1728-a71e-2c03-bb9e-b4c61ccd084d.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/c8c6c562-4e05-de4a-cb6f-29fdb68b3f97.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/b81380b4-3455-7792-0049-43d9aefff812.png)

ワークスペース パッケージ として C50 を登録できたので、次は Apache Spark クラスターにこれをインストールするため、ワークスペース パッケージ から選択を行います。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/24827b09-3d40-318b-cb87-ea72ba871582.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/e0be1744-f030-2b00-1589-9170472b670c.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/05fdd1d3-07f5-858b-4904-708fc3034301.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/374f6f5b-3aad-f3ba-1079-3c26867391fc.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/a3e6d6ed-acc1-e65c-279c-64f98a2782fb.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/a77c030c-5bb8-69b5-516c-b544e7426b6f.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00018.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/2df744d0-9884-f6d7-b628-891e622108d6.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/649ffeaf-9bb1-0f8b-b9b6-87dd304a1093.png)

ここで、インストールには時間がかかるので、気長に待ちます。

そして、インストールは失敗します。エラーは以下の通りです。

```
ProxyLivyApiAsyncError
LibraryManagement - Spark Job for Small3NodesNoAS in workspace workshop-demo-for-ricoh in subscription ********-****-****-****-************ failed with status: 
{"id":2,"appId":"application_1671094646994_0001","appInfo":{"driverLogUrl":"http://vm-44405081:8042/node/containerlogs/container_1671094646994_0001_01_000001/trusted-service-user","sparkUiUrl":"http://vm-44405081:8088/proxy/application_1671094646994_0001/","isSessionTimedOut":null,"isStreamingQueryExists":"false","impulseErrorCode":"Spark_Ambiguous_NonJvmUserApp_ExitWithStatus1","impulseTsg":null,"impulseClassification":"Ambiguous"},"state":"dead","log":["In install.packages(\"C50\", contriburl = \"file://usr/lib/library-manager/bin/lmjob/Small3NodesNoAS/libraries/R/\") :","  installation of package ‘C50’ had non-zero exit status","22/12/15 08:59:39 INFO ","22/12/15 08:59:39 INFO Ran Rscript -e 'install.packages(\"C50\", contriburl=\"file://usr/lib/library-manager/bin/lmjob/Small3NodesNoAS/libraries/R/\")' successfully","22/12/15 08:59:39 INFO Running Rscript -e 'library(\"C50\")'","Error in library(\"C50\") : there is no package called ‘C50’","Execution halted","22/12/15 08:59:40 ERROR b''","22/12/15 08:59:40 INFO Cleanup following folders and files from staging directory:","22/12/15 08:59:40 INFO Staging directory cleaned up successfully"],"registeredSources":null}
```

ノートブックを作成し、パッケージを呼び出してみます。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/86fa1148-9562-3f0c-e4bb-d61a1dd76052.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/17e7997e-8c5e-855d-2fe3-4f17772e92f0.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00022.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/be2395fd-0584-a77b-53ec-b391f52fb6e8.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/93ab11e7-531b-1e34-a305-e7a87e802739.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00024.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/32d5fbbb-7ebf-d84e-f2d6-ab1035981815.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00025.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/7143b154-87c2-7496-91ea-2a441ecaf0db.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00026.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/43b7d85a-71df-66f9-20d5-ed618e38a6df.png)

インストールされているパッケージの一覧に C50 はありません。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/a15e7d53-347f-4148-1083-8570b13fa16c.png)

そして、パッケージを呼び出そうとするとエラーになりました。


## 解決方法

パッケージの依存関係を解決します。

ただ、依存関係を特定した上で、当該 Apache Spark クラスターのノードにどのパッケージがインストール済みか(※)、そしてそれぞれの依存パッケージのバージョンがインストールしようとしているパッケージの要件を満たしているか、確認するのは大変です。

※例えば Spark 3.3 ランタイムであれば、インストール済みのパッケージのリストは [こちら](https://learn.microsoft.com/azure/synapse-analytics/spark/apache-spark-33-runtime#r-libraries-preview) にあります。

そこで、いったん ノートブック セッション パッケージ として依存関係を含めて目当てのパッケージをインストールし、そのログから ワークスペース パッケージ としてインストールする際に必要な依存パッケージを特定すると、誰でも簡単にこの問題を解決することができます。

その流れを以下に示します。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00028.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/95744a2b-d748-b6d2-90b8-e45928042c77.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00029.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/92803bb2-2a84-cb30-c9c3-0145241367da.png)

`install.packages("C50")` の出力には以下のような文字列が含まれています。

```
also installing the dependencies ‘libcoin’, ‘mvtnorm’, ‘Formula’, ‘inum’, ‘partykit’, ‘Cubist’

trying URL 'https://cloud.r-project.org/src/contrib/libcoin_1.0-9.tar.gz'
Content type 'application/x-gzip' length 992315 bytes (969 KB)
==================================================
downloaded 969 KB

trying URL 'https://cloud.r-project.org/src/contrib/mvtnorm_1.1-3.tar.gz'
Content type 'application/x-gzip' length 166421 bytes (162 KB)
==================================================
downloaded 162 KB

trying URL 'https://cloud.r-project.org/src/contrib/Formula_1.2-4.tar.gz'
Content type 'application/x-gzip' length 164214 bytes (160 KB)
==================================================
downloaded 160 KB

trying URL 'https://cloud.r-project.org/src/contrib/inum_1.0-4.tar.gz'
Content type 'application/x-gzip' length 12142 bytes (11 KB)
==================================================
downloaded 11 KB

trying URL 'https://cloud.r-project.org/src/contrib/partykit_1.2-16.tar.gz'
Content type 'application/x-gzip' length 2121360 bytes (2.0 MB)
==================================================
downloaded 2.0 MB

trying URL 'https://cloud.r-project.org/src/contrib/Cubist_0.4.1.tar.gz'
Content type 'application/x-gzip' length 1523257 bytes (1.5 MB)
==================================================
downloaded 1.5 MB

trying URL 'https://cloud.r-project.org/src/contrib/C50_0.1.7.tar.gz'
Content type 'application/x-gzip' length 304504 bytes (297 KB)
==================================================
downloaded 297 KB

Loading required package: usethis
* installing *source* package ‘mvtnorm’ ...
** package ‘mvtnorm’ successfully unpacked and MD5 sums checked
** using staged installation
```

そして、出力は

```
* DONE (C50)

The downloaded source packages are in
	‘/tmp/RtmplbLWPy/downloaded_packages’
[notebook] install.packages pkgs=C50 cost [101s] time:2022-12-15 16:08:45
```

という形でエラー無く `DONE` となっており、`library()` の結果に `C50` は含まれていますし、

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/49f6b8e5-9c38-6740-2dba-269ffaa286b4.png)

`library(C50)` でパッケージの読み込みもできます。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00031.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/bfe80ff5-d68c-b8eb-09c2-4a0e709b13cf.png)

ワークスペース パッケージ としてパッケージをインストールする際に同時に必要となる依存パッケージは、上記の出力に含まれる `.tar.gz` の URI から `wget` 等でダウンロードしてくれば良いのです。


そして、Apache Spark プールのクラスターに、ワークスペース パッケージ からインストールを行います。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00032.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/859e94a5-a2cc-f2df-ce06-fa3153e2f0fa.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/8d9c7fd4-cf9d-a4a6-5228-953a8fa4db86.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00034.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/7a2d880a-ff78-30e0-c49f-dc229fe0ce28.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00035.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/008f4c32-46a2-2a3c-5e9c-9de556bdfc20.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00036.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/5c084240-5f6d-0a2c-b1c6-00cdb3baf31f.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00037.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/43670cb3-c56b-476b-4d1c-8db24abad5ef.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00038.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/3911f79c-92ef-a5e6-02bd-2e110eca6fff.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00039.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/37dbb056-7dc6-c7b5-cf01-370776d1b44b.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/4cee6a1a-212b-beb9-c2e2-c3153d55f024.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/068646a4-6af7-baa1-b24e-fd24d14c81dd.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00042.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/eafa60cd-9238-d91f-679c-df14a3d0e66c.png)

インストールに成功しました。それでは、ワークスペース パッケージ からインストールしたパッケージを、ノートブックから呼び出してみましょう。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00043.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/6aecfb18-d932-4472-2acf-625aab7a952f.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00044.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/0bd2aece-d926-8036-338b-c2bd90f4a701.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00045.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/2ad5eb08-0a6b-237a-9648-c97d2d2caa99.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00046.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/dee59176-0052-589d-6053-a734d78e038e.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00047.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/856b10a7-8bf3-eab6-065c-efb218fa29c3.png)

成功です。

最後に、セッションを一度終了しても、ワークスペース パッケージ としてインストールされたパッケージが再度利用できることを確認しておきましょう。

![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00048.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/a3140b50-20f6-7e51-85cf-a05bc50c7068.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00049.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/408d25a6-a321-71a9-28e9-40ec647f020e.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/5ee1fdab-a93e-6ffc-1ec8-132fdceaa75f.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00051.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/85b7e8fa-6998-4ce9-021b-028eb441e51e.png)
![Use-your-own-R-packages-as-workspace-ones-on-Azure-Synapse-Analytics-Apache-Spark-Pool-00052.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17549/997e89b8-e727-c1bf-7bae-a86d83627631.png)

問題ありません。これで、Apache Spark クラスターとのセッション状態とは関係無く、R パッケージを恒久的に利用できるようになりました。


## まとめ

[Azure Synapse Analytics](https://learn.microsoft.com/azure/synapse-analytics/) の [Apache Spark プール](https://learn.microsoft.com/azure/synapse-analytics/spark/apache-spark-pool-configurations) で R言語を利用する場合、かつ自前のパッケージをインストールしたり ワークスペース パッケージ を利用する場合に、自分で依存関係を解決する方法を解説しました。

少し回り道にはなりますが、一度 ノートブック セッション パッケージ として CRAN 等を使ってインストールすることで、依存パッケージをバージョンや URI も含めて特定することができ、誰でも簡単に R パッケージのインストールを恒久化することができます。

Azure Synapse Analytics 上で R によるデータ分析をゴリゴリやる方には必須知識だと思いますので、ぜひお役立てください。


## See also

* [R 開発者向けガイド - R プログラミング - Azure Architecture Center | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/architecture/data-guide/technology-choices/r-developers-guide)