Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
RパッケージでRustを使うには: extendr入門 / extendr-pkg-dev
Search
yutannihilation
May 30, 2021
Programming
8k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RパッケージでRustを使うには: extendr入門 / extendr-pkg-dev
第92回R勉強会
の発表スライドです。
(
ウェブ版
をPDFエクスポートしたものですが、Slidevの使い方がわからず画像が消えてしまっています...)
yutannihilation
May 30, 2021
More Decks by yutannihilation
See All by yutannihilation
🦀
yutannihilation
2
870
rayshader入門 / rayshader-tokyor88
yutannihilation
0
1.2k
RとApache Arrow / r-and-apache-arrow
yutannihilation
4
7.6k
そろそろ使ってみませんかApache Arrow / why-dont-you-arrow-now
yutannihilation
2
1.2k
A Graphical Introduction to tidyr's pivot_*()
yutannihilation
5
5.4k
tidyr 1.0.0の新機能 pivot_*() / tidyr-pivot
yutannihilation
4
11k
RとApache Arrow
yutannihilation
0
3.5k
Yet Another Introduction to tidyeval
yutannihilation
10
8.3k
Introduction to gghighlight
yutannihilation
6
3k
Other Decks in Programming
See All in Programming
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
300
速く作れる。その次は、速く確かめられる開発へ 〜AIネイティブ開発を支える、Shift Down〜 / Can build fast. Next, moving to development where we can verify fast.
rkaga
6
4.6k
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
3.6k
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.3k
AHC070解法紹介
eijirou
0
130
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
670
巨大モノリシックアプリ モダン化大作戦
ktcryomm
1
1.1k
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
270
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
190
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
9
5k
iOSDC2026登壇資料.pdf
riofujimon
0
190
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
230
Featured
See All Featured
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
For a Future-Friendly Web
brad_frost
183
10k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
880
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
670
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Darren the Foodie - Storyboard
khoart
PRO
4
3.9k
My Coaching Mixtape
mlcsv
0
320
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
440
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
530
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
42k
Agile that works and the tools we love
rasmusluckow
331
22k
Transcript
Rパッケージで Rustを使うには: extendr入門 Hiroaki Yutani (@yutannihilation) Tokyo.R#92
ドーモ! : @yutannihilation 好きな言語: R、Rust、忍殺語 最近の趣味: ガスコンロの電子楽器 をつくってます
Rユーザのための RStudio[実践]入 門 第2版! https://gihyo.jp/book/2021/978- 4-297-12170-9 紙は6月3日、電子は5 月31日発売です。
extendr
extendrとは? RustとRを連携させるためのフレームワーク RからRustを使うだけではなく、RustからRを使 うこともできる(つまり、Rustの中でggplot2を 呼び出してプロットしたり、とかできるらしい) なぜか私も中の人です…
なぜRust? → そこにRustがあるから!! (誰か教えてください…)
※今日話さないこと Rustの何が素晴らしいのか Rust入門 Rust側からRを操作する方法 R MarkdownのRust engineとか、パッケージ外 でのextendrの使いみち
extendrの愉快な仲間たち libR-sys(Rust): RのC APIにbindgenで生成したバインディング extendr(Rust): libR-sysを使いやすくラップしたフレームワーク rextendr(Rパッケージ): Rからextendrを使うためのユーティリティ (usethisパッケージのような立ち位置)
準備
Rustのインストール macOS / Linux: ふつうにRustをインストール(ググる) Windows MSVCのtoolchainに加えて、64bit/32bit GNU用 のtargetを追加する必要がある rustup
default stable-msvc rustup target add x86_64-pc-windows-gnu rustup target add i686-pc-windows-gnu
rextendrパッケージのインストール GitHubからインストール devtools::install_github("extendr/rextendr")
パッケージのセットアップ
RStudioからパッケージ作成
Roxygenを使うように設定変更 NAMESPACEを上書き Build optionsを設定 Build > Configure Build Tools… >
Generate documentation with Roxygen に を入れる 不要なファイルを削除 R/hello.R man/hello.Rd usethis::use_namespace() ` ` ` `
extendrのデフォルト設定を生成 rextendr::use_extendr() ✓ Creating src/rust/src. ✓ Writing 'src/entrypoint.c' ✓ Writing
'src/Makevars' ✓ Writing 'src/Makevars.win' ✓ Writing 'src/.gitignore' ✓ Writing src/rust/Cargo.toml. ✓ Writing 'src/rust/src/lib.rs' ✓ Writing 'R/extendr-wrappers.R' ✓ Finished configuring extendr for package myextendr. • Please update the system requirement in DESCRIPTION file. • Please run `rextendr::document()` for changes to take effect
生成されたファイル . ├── R │ └── extendr-wrappers.R ... └── src
├── Makevars ├── Makevars.win ├── entrypoint.c └── rust ├── Cargo.toml └── src └── lib.rs
いじるファイル src/rust: extendrを使ったRustのcrate。開発のメインはこ こ。
基本いじらないファイル Makevars, Makevars.win: パッケージインストール時に cargo build が走るように する設定。 entrypoint.c: コンパイラにシンボルを勝手に消されないためのおま
じない。 R/extendr-wrappers.R: Rustの関数から自動生成されたRの関数。 ` `
src/rust/Cargo.toml [package] name = 'myextendr' version = '0.1.0' edition =
'2018' [lib] crate-type = [ 'staticlib' ] [dependencies] extendr-api = '*'
src/rust/src/lib.rs(一部省略) use extendr_api::prelude::*; /// Return string `"Hello world!"` to R.
/// @export #[extendr] fn hello_world() -> &'static str { "Hello world!" } extendr_module! { mod myextendr; fn hello_world; }
src/rust/src/lib.rs よく使う関数をまとめて読み込み /// (3つ)のコメントはそのままRoxygenのコ メントになる これをつけるとRの関数が自動生成! use extendr_api::prelude::*; ` `
/// Return string `"Hello world!"` to R. /// @export #[extendr]
src/rust/src/lib.rs 関数をエクスポートしてRが認識できるように登録 (routine registration)してくれるマクロ。 新 しく関数を追加したらここに入れる必要がある。 extendr_module! { mod myextendr;
fn hello_world; }
開発の流れ
開発の流れ 1. Rustのコードを編集 2. rextendr::document() でRのコードを自動生成(Rust のコードのコンパイルもこれがやってくれる) 3. (必要あれば)生成されたコードをRの側でいい感 じにラップする
4. devtools::load_all() (やテスト)で動作確認 ` ` ` `
rextendr::document() ` ` > rextendr::document() ✓ Saving changes in the
open files. ℹ Generating extendr wrapper functions for package: myextendr. ! No library found at src/myextendr.so, recompilation is requi Re-compiling myextendr ─ installing *source* package ‘myextendr’ ... (382ms) ** using staged installation ** libs rm -Rf myextendr.so ./rust/target/release/libmyextendr.a en gcc -std=gnu99 -I"/usr/share/R/include" -DNDEBUG -fpic cargo build --lib --release --manifest-path=./rust/Cargo.to Updating crates.io index
生成されるファイル . ... ├── NAMESPACE <- @exportが反映される ├── R │
└── extendr-wrappers.R <- Rustの関数から自動生成 └── src ├── myextendr.so <- libmyextendr.aを使ってビルドされた └── rust 共有オブジェクト └── target <- Rustの生成物が入るディレクトリ └── release ├── libmyextendr.a <- Rustのコードの静的ライブラリ ... (OSによって拡張子は違う)
自動生成されたRの関数 Rust R /// Return string `"Hello world!"` to R.
/// @export #[extendr] fn hello_world() -> &'static str { "Hello world!" } #' Return string `"Hello world!"` to R. #' @export hello_world <- function() .Call(wrap__hello_world)
実行結果 #> [1] "Hello world!" devtools::load_all(".") hello_world()
例1) i32 (integer)を引数に取る 関数
自動生成されたRの関数 Rust R /// @export #[extendr] fn add(x: i32, y:
i32) -> i32 { x + y } #' @export add <- function(x, y) .Call(wrap__add, x, y)
実行結果 #> [1] 3 #> Error in add(1:2, 2:3) :
#> Input must be of length 1. Vector of length >1 given. devtools::load_all(".") # 引数の型は i32 だけど実数も渡せる add(1, 2) # 長さ1以上だとエラーになる add(1:2, 2:3)
例2) Vec<i32>を引数に取る関数
自動生成されたRの関数 Rust R #[extendr] fn mult(x: Vec<i32>, y: i32) ->
Vec<i32> { x .iter() .map(|n| n * y) .collect::<Vec<_>>() } #' @export mult <- function(x, y) .Call(wrap__mult, x, y)
実行結果 #> [1] 10 20 30 40 50 devtools::load_all(".") mult(1:5,
10)
例3) struct
struct…? 環境としてエクスポートされるので状態を持つこ とができる たまに便利(正規表現のキャッシュを持たせてい る例: rr4r)
自動生成されたRの関数 Rust struct Counter { i: i32, } /// @export
#[extendr] impl Counter { fn new() -> Self { Self { i: 0 } } fn count(&mut self) -> i32 { self.i = self.i + 1; self.i } }
自動生成されたRの関数 R #' @export Counter <- new.env(parent = emptyenv()) Counter$new
<- function() .Call(wrap__Counter__new) Counter$count <- function() .Call(wrap__Counter__count, self) #' @rdname Counter #' @usage NULL #' @export `$.Counter` <- function (self, name) { func <- Counter[[name]]
実行結果 #> [1] 1 #> [1] 2 devtools::load_all(".") cnt <-
Counter$new() cnt$count() cnt$count()
その他こまごました話 (時間があれば)
その他 文字列関連はlifetimeを意識しないと使えないの で初心者にはハードモード。数値計算系からはじ めるのがおすすめ。 Windowsのセットアップはやや面倒だけど、 GitHub Actionsでビルド済みのバイナリを配布し たりできるはず(調査中) CRANにはすでにextendrを使っているパッケージ も存在する
まとめ
まとめ extendrを使うとマクロの魔術でRustの関数から Rの関数を生成してくれる。 関数の引数の対応づけはRcppやcpp11と同じノ リ。慣れている人はわりとすぐに使えるはず。 ちなみに、今回はすべてRustのデータ型に変換 するタイプだったが、SEXPのまま扱うことも できる(ここはよく理解できていない) フィードバックお待ちしています!
r-wakalangにrustチャンネルをつくり ました
References extendr: https://github.com/extendr/extendr extendrのロゴはCC-BY-SA 4.0ライセンスで配布 されています: https://github.com/extendr/artwork.