ドーモ、SREチームの湯谷(@yutannihilation)です。
表題のとおり、kintoneアプリのデータをRのdata.frameとして取得するパッケージ「kntnr」をCRANに公開しました。これで、Rでデータ分析もグラフ作成*1もやり放題です。
※あくまで個人の趣味として業務の合間につくったものです。自己責任でお使いください。
インストール
install.packages()
でインストールしてください。
install.packages("kntnr")
使い方
認証
kntnrパッケージは、以下の情報を環境変数として受け取ります。
KNTN_URL
: cybozu.com の URL を指定します(サブドメイン.cybozu.com
)KNTN_AUTH_TYPE
: 認証の方式を指定します。password
(ユーザ名とパスワードを使った認証)またはtoken
(APIトークンを使った認証)KNTN_AUTH
:ユーザ名:パスワード
をBase64エンコードした文字列、またはAPIトークン
Rのセッションに環境変数をセットする方法は色々ありますが、kntn_set_auth()
関数を使うと、インタラクティブにこれらの環境変数を設定できます。認証方式はauth_type
引数で指定できます。
library(kntnr) # デフォルトはユーザ名とパスワードを使った認証 kntn_set_auth() # トークンを使った認証 kntn_set_auth(auth_type = "token")
間違った情報を入力してしまったときは、overwrite
引数にTRUE
を指定すると上書きできます。
kntn_set_auth(overwrite = TRUE)
レコードの取得
kntn_records()
は、指定したkintoneアプリからレコードを取得します(レコードの一括取得API)。app
にはアプリ番号(例:アプリのURLがhttps://サブドメイン.cybozu.com/k/123/
なら123
の部分)を指定します。
kntn_records(app = 123)
レコード一括取得APIで一度に取得できるレコード数は、最大500レコード、デフォルトでは100レコードとなっています(本記事執筆時点)。kntnrパッケージでは、取得したいレコード数が一度に取得したいレコード数を超えている場合は、自動でリクエストを分割してくれます。
取得する最大レコード数はmax_records
引数で指定します。デフォルトは1000レコードです。一度に取得するレコード数はrecords_per_request
で指定できます。デフォルトは100レコードです。たとえば以下のように指定すれば、最大200レコードを取得するリクエストを2回まで行います。
kntn_records(app = 123, max_records = 400, records_per_request = 200)
具体的に、こういうアプリがあるとすると、
以下のようなdata.frame(正確にはtibble)としてデータをRに取ってくることができます。
d <- kntn_records(app = 123) #> Getting 100 records from 0 d #> # A tibble: 5 × 15 #> レコード番号 作業者 更新者 作成者 文字列__1行_ ステータス ドロップダウン #> <chr> <list> <chr> <chr> <chr> <chr> <chr> #> 1 5 <chr [1]> cybozu cybozu 懇親会 未申請(下書き) 営業部 #> 2 4 <chr [0]> cybozu cybozu 商談 承認 営業部 #> 3 3 <chr [1]> cybozu cybozu 商談 未申請(下書き) 営業部 #> 4 2 <chr [1]> cybozu cybozu イベント 未申請(下書き) 営業部 #> 5 1 <chr [1]> cybozu cybozu 会社Aへの往訪 上長確認中 営業部 #> # ... with 8 more variables: `$revision` <int>, 数値_0 <dbl>, ユーザー選択 <list>, #> # 更新日時 <dttm>, 文字列__複数行__ <chr>, 作成日時 <dttm>, 計算 <chr>, `$id` <int>
ここで、作業者
という列に注目してください、tibbleは列名の下にその列の型が表示されますが、<list>
となっています。これは、作業者
フィールドは複数の値が入る可能性があるためです。kntnrは、こうしたフィールドはlistでラップするようにしています。
ネストしている列を展開する
こうしたネストしたフィールドは、tidyrパッケージのunnest()
で展開することができます。やってみましょう。
d %>% tidyr::unnest(d, 作業者) %>% select(レコード番号, 作業者, 文字列__1行_) #> # A tibble: 4 × 3 #> レコード番号 作業者 文字列__1行_ #> <chr> <chr> <chr> #> 1 5 cybozu 懇親会 #> 2 3 cybozu 商談 #> 3 2 cybozu イベント #> 4 1 cybozu 会社Aへの往訪
<list>
だった作業者
の列がしっかり<chr>
(character
)に展開されています。
ただし、レコード数がひとつ減っていることに気付くでしょうか。これは、レコード番号
が4
のレコードは作業者
が空だったためです。unnest()
では、指定したカラムにデータが存在しないレコードは消えてしまいます。なるほどこれはこれで正しい挙動でしょう。しかし、dplyrパッケージのleft_join()
のようにレコードがなければNA
で埋めてほしいときもあります。
そんなときのためにkntn_unnest()
という関数をつくりました。kntn_unnest()
は、データが存在しないレコードはNA
で埋めてくれます。unnest()
と違って列名を指定することはできません。すべてのネストした列を展開します。(kntn_unnest()
の挙動はまだ模索中なので、今後変更するかもしれません)
d %>% kntn_unnest() %>% select(レコード番号, 作業者, 文字列__1行_) #> # A tibble: 5 × 3 #> レコード番号 作業者 文字列__1行_ #> <chr> <chr> <chr> #> 1 5 cybozu 懇親会 #> 2 4 <NA> 商談 #> 3 3 cybozu 商談 #> 4 2 cybozu イベント #> 5 1 cybozu 会社Aへの往訪
ファイルのダウンロード
kntn_file()
は、指定したキーのファイルを取得します(ファイルダウンロードAPI)。その際、httrパッケージのcontent()
関数を使って読み取ることができるファイル形式であれば、自動で適切な形式に変換してくれます。変換したくない場合は、as="text"
またはas="raw"
を指定してください。
d <- kntn_records(app = 234) d$添付ファイル[[1]] #> # A tibble: 1 × 4 #> fileKey name #> <chr> <chr> #> 1 12345678901234567890asdfghjklasdfghjklasdfghjklas data.csv #> # ... with 2 more variables: contentType <chr>, size <chr> # CSVファイルはdata.frameとして読み込まれる x <- kntn_file(app = 234, fileKey = d$添付ファイル[[1]]$fileKey[1]) # CSVファイルはテキストとして読み込まれる x <- kntn_file(app = 234, fileKey = d$添付ファイル[[1]]$fileKey[1], as = "text")
その他のAPI
kintoneには他にも様々なAPIがありますが、kntnrパッケージはkintoneアプリのデータ取得に特化しています。今のところレコード取得とファイルダウンロードにしか対応していません。
最後に
需要があるのかまったく分からないまま公開したパッケージですが、よければ使ってみてください。何かあれば、GitHubレポジトリのIssuesかTwitterあたりでお知らせいただけると助かります。
(この記事はSREチームの業務とはまったく関係ないですが、)SREチームでは、Rが好きなエンジニアや、周囲でまったく使っている人がいないRの話でも会社ブログに書かせてくれるようなあたたかい職場で働きたいエンジニアを募集しています。SREの募集要項はこちらです。
*1:kintoneではグラフ作成も思いのままにできますが、ggplot2に慣れてしまうとちょっと物足りないときがあります。