読者です 読者をやめる 読者になる 読者になる

Rでkintoneのデータを取得するパッケージをCRANで公開しました

ドーモ、SREチームの湯谷(@yutannihilation)です。

表題のとおり、kintoneアプリのデータをRのdata.frameとして取得するパッケージ「kntnr」をCRANに公開しました。これで、Rでデータ分析もグラフ作成*1もやり放題です。

CRAN - Package kntnr

※あくまで個人の趣味として業務の合間につくったものです。自己責任でお使いください。

インストール

install.packages()でインストールしてください。

install.packages("kntnr")

使い方

認証

kntnrパッケージは、以下の情報を環境変数として受け取ります。

  • KNTN_URL: cybozu.com の URL を指定します(サブドメイン.cybozu.com
  • KNTN_AUTH_TYPE: 認証の方式を指定します。password(ユーザ名とパスワードを使った認証)またはtokenAPIトークンを使った認証)
  • 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)

具体的に、こういうアプリがあるとすると、

f:id:cybozuinsideout:20161122133827p:plain

以下のような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レポジトリのIssuesTwitterあたりでお知らせいただけると助かります。

(この記事はSREチームの業務とはまったく関係ないですが、)SREチームでは、Rが好きなエンジニアや、周囲でまったく使っている人がいないRの話でも会社ブログに書かせてくれるようなあたたかい職場で働きたいエンジニアを募集しています。SREの募集要項はこちらです。

*1:kintoneではグラフ作成も思いのままにできますが、ggplot2に慣れてしまうとちょっと物足りないときがあります。