LoginSignup
27

More than 3 years have passed since last update.

Rパッケージ探索のススメ

Posted at

概要

  • Rパッケージ情報収集のオススメ
  • Rパッケージ検証のオススメ
  • Rパッケージ活用のオススメ(今後に期待)

前書き

 「キミががんばって実装したこの関数だけど、CRANで見つけたパッケージを使えばすぐにできたよ」

 これはR Advent Calendar 2019 18日目の記事になります(2年連続18日担当)。

 R言語は多種多様なパッケージが公開されている点がオススメとして語られるときがありますが、tidyverseやcaretなどの有名なもの以外にどういう有用なパッケージがあるかは杳として知れません。
 TokyoR#82のLTにてRにまつわる推しを紹介したり、Twitterや懇親会などでパッケージ情報をどういう風に集めているか聞かれたりとしばしばあったため、情報集めや試す際にやっていること・心掛けていることなどを本記事でまとめました。

 流れは「パッケージを知る」、「パッケージを試す」、「パッケージを使う」の三段階に分けており、中でも「パッケージを知る」と「パッケージを試す」に的を絞った内容となっています。
 対象はRをある程度使えるようになった人を想定しております。

パッケージを知る

 パッケージを知る経緯には、「ブログやまとめ記事、ソーシャルアカウントなどで紹介されて知るタイプ(受動)」と「興味がある領域を検索したり調べたりして自分で見つけるタイプ(能動)」がありますが、ここでは前者にフォーカスして記載しています(後者のタイプは自分で勝手にやっていく認識)。
 なお、「パッケージを知る」は「新しいパッケージを知る」と「新しい機能を知る」などに分けられますが、本記事では両方を対象にして特段区別していません。

ブログ

 Rに関するブログを掲載するサイトは数多くありますが、定期にR言語の有用なブログ記事が集まるサイトには以下などがあり、こちらはウォッチすると良いでしょう。

 Rに関するブログが集まる(サイト登録型)R-bloggersを始め、
 RStudio社が公開するパッケージの最新情報が集まるRStudio Blogの他に、
 日本語ではほとんど情報がないRユーザーのために書かれたTensorFlowの話題がTensorFlow for R Blogでは多く掲載されています。

まとめ記事

 この節ではRに関するコンテンツをまとめていたり、定期的にパッケージ情報を共有するサイトとして、R WeeklyとR Viewsに触れます。

R Weekly

 かつては「ぞうさん通信」という、大体毎週月曜日に更新されていたR関連記事まとめコンテンツがありました。
 当時活動していた日本のRユーザーたちはそこに取り上げられることを密かな楽しみにしていたという説もありますが(要出典)、管理者の負担が大きく2015年10月には惜しまれつつも停止となりました(#ありがとうぞうさん)。

 そんな背景は関係ないですが、R Weeklyは2016年5月から始まったRに関するコンテンツを作成者が発信するサイトです。
 サイトを登録するR-bloggersと似ていますが、登録はページ単位で都度行い、週毎にまとまって見ることができます(「Live」のページで日毎にサブミットされたサイトが閲覧できます)。

RWeekly.org.png

 また、RユーザーらしくRから投稿する関数も提供されています。

R Views

 R Viewsは先ほど触れたRStudio Blogと同じくRStudio社が管理していますが、こちらはRコミュニティ向けの情報を共有するサイトになっています。

rviews..png

 このR Viewsでは毎月中旬以降に「"Top 40" New R Packages」というタイトル(2018年の3月までは「New Package Picks」)で、先月の注目パッケージ(CRAN)を紹介しております。
 過去分を含めて分析するだけでもなかなか面白い結果が得られそうですね(むしろ、それをアドベントカレンダーのネタにすべきだったのでは)。

 「Data」や「Statistics」、「Machine Learning」などのカテゴリに分けて紹介されており、「Visualization」に至っては眺めるだけでも楽しく毎月の癒しとなるでしょう。

October 2019 Top 40 New Packages Vis.png

ソーシャルアカウントなど

 パッケージ情報収集にあたりフォローすべきTwitterアカウントや、r-wakalangのチャンネルを紹介します。

Twitterアカウント

 Twitterでは以下のような方々がしばしば良さそうなパッケージを紹介するツイートをしています。

 また、前述したブログの更新情報をツイートするアカウントもありますので、フォローしておくと良いかもしれません。

 なお、CRANに追加・更新・削除されたパッケージの情報を閲覧できるCRANberriesのフィードをツイートするCRAN Package Updatesもありますが、タイムラインが埋まるためリストに登録して定期的に読むくらいが良いでしょう。
 「#rstats」や「#TidyTuesday」もパッケージに限らず適度に眺めていると面白いです。

r-wakalang

 r-wakalangはR言語に関する質問や情報共有などを行うSlackのスペースです。
 詳しい説明は「r-wakalang へようこそ」や「Rおじさんの異常な即回答または私は如何にして心配するのを止めてr-wakalangで回答するようになったか」をお読みください。

 こちらの中で広い範囲での情報収集では「feedチャンネル」がオススメですが、パッケージに限定した情報を定期的に得たい場合には不向きです(単発であれば質問しましょう)。
 そういうときはチャンネルを作り、自らが率先して情報を提供していくと集まっていくようになります(tidymodelsチャンネルは広がり始めていてよいが、easystatsやr-confはまだまだ)。

GitHubリスト

 パッケージリストをGitHubにまとめたリソース群がWeb上に公開されています。
 能動的にパッケージを調べる際にはこれらを最初に見て当たりをつけたり、探索元とするパッケージを特定することをオススメします。

Awesome R

 R言語で「Awesome」といえば『前処理大全』の著者で知られるAwesomeデータサイエンティスト本橋さんを想起する方も多いでしょうが、ここではAwesome Machine LearningをインスパイアしたR版リストを指します。

AWESOME R.png

 また、パッケージではなくRに関するコンテンツをまとめたAwesome Rもあります。

非公式CRAN Task View

 CRAN Task Viewはテーマ別にパッケージをグループ分けしたものですが、非公式CRAN Task Viewとして個人的にグループ化したり、スクレイピングしたリストを公開している方々もいます。

検索サイト

 CRANはリポジトリでありユーザーによるパッケージ検索はとてもしづらいページですが、METACRANは検索に重きをおかれたサイトとなっています。

METACRAN.png

 また、rdrr.ioはドキュメントがメインですが、RパッケージをCRANやGitHubだけでなくBioconductorやR-Forgeを含めたリポジトリから検索もできます。

rdrr.io.png

パッケージを試す

 知るないしは見つけたパッケージは自身のニーズを適しているかどうか検証する必要があります。
 自分のローカル環境を手軽に試すのも悪くはありませんが、再利用性やパッケージ・システムの依存関係などの観点からDockerを用いて実行環境を切り替えることに慣れましょう。

Dockerを使う

 Dockerを使うと実行環境を容易にスクラップ&ビルドができ、なおかつ再現も可能となるため、パッケージの検証には最適と言えるでしょう。
 Dockerfileやdocker-compose.ymlが自前で書けることに越したことはありませんが、Dockerがさっぱりわからないという人はRパッケージと同じで、まずは道具として使うことから始めると良いでしょう。

 ドキュメントをまったく書いていなくて申し訳ないですが、以下は以前に私が作成してDocker Hubに公開したDockerコンテナになります。
 こちらのDockerfileやdocker-compose.ymlはGitHubに上げてあり、docker-compose buildでビルドしています(ただし、CentOS7が最新の時期に作っています)。

 こちらを用いてGoogle Cloud PlatformのGoogle Cloud Engine(Container-Optimized OS)上で動かす手順は次の通りです(Cloud Shellで実行するとより手軽です)。
 まずは動かすインスタンスを作ります。ここでファイアウォール設定や静的IP設定も合わせて行っています。なお、[PROJECT_ID]は適宜自身の環境に変え、スペックやリージョン・ゾーンもお好みで変更してください。

事前準備
# ファイアウォール設定
$ gcloud compute firewall-rules create analytics-rstudio --project [PROJECT_ID] --allow tcp:80 --priority 100 --target-tags analytics-rstudio
Creating firewall...⠶Created [https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/firewalls/analytics-rstudio].
Creating firewall...done.
NAME               NETWORK  DIRECTION  PRIORITY  ALLOW   DENY  DISABLED
analytics-rstudio  default  INGRESS    100       tcp:80        False

# 静的IP設定
$ gcloud compute addresses create analytics-rstudio --region asia-northeast1 --project [PROJECT_ID]
Created [https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/asia-northeast1/addresses/analytics-rstudio].
$ analytics_rstudio_ip=$(gcloud compute addresses list --project [PROJECT_ID] | grep analytics-rstudio | awk '{print $2}')

# インスタンス作成(IPはマスキングしています)
$ gcloud compute instances create analytics-rstudio --image-family=cos-stable --image-project=cos-cloud --machine-type n1-highmem-2 --boot-disk-type pd-ssd --boot-disk-size 80GB --zone asia-northeast1-c --tags analytics-rstudio --address $analytics_rstudio_ip --project [PROJECT_ID]
Created [https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/asia-northeast1-c/instances/analytics-rstudio].
WARNING: Some requests generated warnings:
  - Disk size: '80 GB' is larger than image size: '10 GB'. You might need to resize the root repartition manually if the operating system does not support automatic resizing. See https://cloud.google.com/compute/docs/disks/add-persistent-disk#resize_pd for details.

NAME   ZONE   MACHINE_TYPE  PREEMPTIBLE INTERNAL_IP EXTERNAL_IP  STATUS
analytics-rstudio  asia-northeast1-c  n1-highmem-2 XXX.X.XXX.XXX  XXX.XXX.XXX.XXX  RUNNING

 次に作成したインスタンスに入って、DockerをpullするだけでRStudio Serverが使えるようになります。

Dockerコンテナを起動
# SSHログイン
$ gcloud compute ssh analytics-rstudio --zone asia-northeast1-c --project [PROJECT_ID]
# 認証
$ docker-credential-gcr configure-docker
/home/[USER_NAME]/.docker/config.json configured to use this credential helper for GCR registries

# Dockerコンテナを起動
$ docker run -d -p 80:80 --restart always yamano357/rpy-mlnlp-rstudio-shiny:latest
$ docker ps -a
CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES
39a48b6e2ede     yamano357/rpy-mlnlp-rstudio-shiny:latest   "/usr/bin/supervisor…"   3 minutes ago    Up 3 minutes     0.0.0.0:80->80/tcp   competent_bhaskara

 ブラウザから途中表示された「EXTERNAL_IP」を次のURLに記載すればRStudio Serverにアクセスできます(「rstudio」を「shiny」にするとshinyのデモアプリが表示)。あとは好きなパッケージを試したり、好きなように使いましょう。

  • http://[EXTERNAL_IP]/rstudio/

rstudio_server.png

 ユーザー名rstudioの初期パスワードをrstudioに設定していますが、build-argオプションでPASSWORDを指定してイメージをビルドすると変更できます。また、ユーザー追加は「useraddコマンド + passwdコマンド」で可能です。

また、Dockerが稼働するローカルPCをホストにする場合は次のコマンドのみで十分です。

ローカルマシン上で使う
$ docker run -d -p 80:80 yamano357/rpy-mlnlp-rstudio-shiny:latest

 こちらの場合はローカルホストで接続します。

 ちなみにこちらのイメージでは、下記リンクに書かれたRパッケージが呼び出せます。Python 3系も使用可能で必要そうなものは大体インストールしてありますが、サイズが大きいので利用時には注意してください。

インストール済みパッケージ数
> nrow(x = installed.packages())
[1] 665

 より手軽にDockerを試すのであればrockerを使いましょう。

 また、Rスクリプト/セッション/ワークスペースからDockerfileを生成するというパッケージもありますが、試していないのでここでは割愛します。

System Requirements

 パッケージを試す時にはパッケージの依存関係以外にシステム要件も考慮する必要があります。
 例えば、sfパッケージではSystemRequirementsに「C++11, GDAL (>= 2.0.1), GEOS (>= 3.4.0), PROJ (>= 4.8.0)」と記載されており、これらがRパッケージとは別にシステムにインストールされていなければいけません。
 これらのバージョンや要件からもDockerを用いることが望ましいわけです。

sf.png

 次のRコードはCRANにあるドキュメントからSystemRequirementsの項目を抜き出し、ファイルに書き込んでいます。

SystemRequirementsの抽出
# CRANリポジトリ
CRAN_REPOS <- "https://cran.ism.ac.jp/"

options(repos = c(CRAN = CRAN_REPOS))
options(timeout = 4000000) 

library(tidyverse)

# 対象外にする基本パッケージ
RBASE_PACKAGES <- c(
  "base", "compiler", "datasets", "graphics", "grDevices", "grid", "methods",
  "parallel", "splines", "stats", "stats4", "tools", "tcltk", "utils"
)

# ローカルパッケージリスト
inst_pkgs <- installed.packages() %>% 
  tibble::as_tibble() %>% 
  dplyr::select(package = Package, local_version = Version) %>%
  dplyr::distinct()
nrow(x = cran_pkgs)
#> [1] 665

# CRANパッケージリスト
cran_pkgs <- remotes:::available_packages() %>% 
  tibble::as_tibble() %>%
  dplyr::select(package = Package, cran_version = Version) %>% 
  dplyr::distinct()
nrow(x = cran_pkgs)
#> [1] 15348

cran_pkgs %>% 
  dplyr::filter(!is.element(el = package, set = RBASE_PACKAGES)) %>% 
  dplyr::anti_join(y = inst_pkgs, by = c("package" = "package")) %>% 
  dplyr::group_by(package) %>% 
  dplyr::group_map(
    .f = function (...) {
      args <- rlang::list2(...)
      system_requirements <- xml2::read_html(
        x = glue::glue(
          "{CRAN_REPOS}web/packages/{PACKAGE_NAME}/index.html",
          CRAN_REPOS = CRAN_REPOS,
          PACKAGE_NAME = args[[2]]$package
        )
      ) %>%   
        xml2::xml_find_all(
          xpath = ".//tr/td[contains(text(), 'SystemRequirements:')]/following-sibling::td"
        ) %>%
        xml2::xml_text(trim = TRUE)

      Sys.sleep(time = 1)   
      if (length(system_requirements) > 0) {
        tibble::tibble(
          package = args[[2]]$package,
          system_requirements = stringr::str_remove_all(string = system_requirements, pattern = "\\n")
        ) %>% 
          readr::write_delim(
            path = "pkg_system_requirements.tsv", 
            delim = "\t", append = TRUE, 
          )
        Sys.sleep(time = 1)
      }

      tibble::tibble(system_requirements = system_requirements) %>% 
        return()
    }
  )

 上記で取得したファイルを読み込み、ローカルにインストールされているパッケージの分をさらに追加します。

ローカル環境中にあるパッケージの分を追記
pkg_system_requirements <- readr::read_delim(
  file = "pkg_system_requirements.tsv", delim = "\t",
  col_names = c("package", "system_requirements"),
  col_types = readr::cols(
    package = readr::col_character(), system_requirements = readr::col_character()
  )
) %>% 
  # 追記
  dplyr::bind_rows(
    inst_pkgs %>% 
      dplyr::group_by(package) %>% 
      dplyr::group_map(
        .f = function (...) {
          arg_list <- rlang::list2(...)
          pkg_desc <- sessioninfo:::pkg_desc(package = arg_list[[2]]$package)
          pkg_system_requirements <- NULL
          if(!is.null(x = pkg_desc$SystemRequirements)) {
            pkg_system_requirements <- pkg_desc$SystemRequirements
          }
          arg_list[[1]] %>% 
            dplyr::mutate(system_requirements = pkg_system_requirements) %>% 
            return()
        } 
      )
  ) %>% 
  dplyr::filter(!is.na(x = system_requirements)) %>% 
  dplyr::select(package, system_requirements)

 これらの結果の文字列を適度に処理して集計すると、次のようになりました。

集計
# システム要件を含むパッケージ数
nrow(x = pkg_system_requirements)
#> [1] 1073
nrow(x = pkg_system_requirements) / nrow(x = cran_pkgs)
#> [1] 0.06991139

pkg_system_requirements %>% 
  dplyr::mutate(
    system_requirements = stringr::str_replace_all(
      string = .$system_requirements, pattern = "\\n", replacement = " "
    )
  ) %>%
  dplyr::mutate(
    system_requirements = stringr::str_remove_all(
      string = .$system_requirements,
      pattern = "\\(.*?\\)|(<.*?>)|(\\\")|( or higher)|(- http://pandoc.org)|(with https support)|(-http://johnmacfarlane.net/pandoc)"
    )
  ) %>%
  tidyr::separate_rows(system_requirements, sep = "[,|;]") %>% 
  dplyr::mutate(
    system_requirements = stringr::str_remove_all(
      string = system_requirements,
      pattern = "\\.$"
    )
  ) %>% 
  dplyr::mutate(system_requirements = stringr::str_to_lower(string = system_requirements)) %>%   
  dplyr::mutate(
    system_requirements = stringr::str_replace_all(
      string = system_requirements,
      pattern = c(
        "compiler$" = "",
        "(gnu scientific library.*)|(gnu gsl)" = "gsl",
        "java jdk.*?\\d+.\\d+" = "java jdk",
        "java jre.*?\\d+.\\d+" = "java jre",
        "java jvm.*?\\d+.\\d+" = "java jvm"
        # ">=.*?\\d+.\\d+" = ""
      )
    )
  ) %>% 
  dplyr::mutate(
    system_requirements = stringr::str_replace_all(
      string = system_requirements, pattern = "( ){2,}", replacement = " " 
    )
  ) %>% 
  dplyr::mutate(system_requirements = stringr::str_trim(string = system_requirements, side = "both")) %>% 
  dplyr::group_by(system_requirements) %>% dplyr::tally() %>% 
  dplyr::filter(n >= 10) %>% dplyr::arrange(dplyr::desc(x = n)) %>% 
  dplyr::mutate(p = (n /  nrow(x = pkg_system_requirements)) * 100)
#> # A tibble: 13 x 3
#>    system_requirements     n      p
#>    <chr>               <int>  <dbl>
#>  1 c++11                 289 26.9  
#>  2 gnu make              154 14.4  
#>  3 java                   83  7.74 
#>  4 pandoc                 50  4.66 
#>  5 gsl                    34  3.17 
#>  6 jags                   29  2.70 
#>  7 python                 21  1.96 
#>  8 gdal                   13  1.21 
#>  9 gmp                    13  1.21 
#> 10 geos                   12  1.12 
#> 11 perl                   12  1.12 
#> 12 fftw3                  11  1.03 
#> 13 linux                  10  0.932

# システム要件のうち約4分の1がC++11

# C++11ではなくC++14に依存したパッケージ
pkg_system_requirements %>% 
  dplyr::filter(stringr::str_detect(string = .$system_requirements, pattern = "C\\+\\+14"))
#> # A tibble: 5 x 2
#>   package   system_requirements  
#>   <chr>     <chr>                
#> 1 IsoSpecR  C++14                
#> 2 multinet  A C++14 compiler     
#> 3 ndjson    zlib, C++14          
#> 4 RcppAlgos C++14, gmp (>= 4.2.3)
#> 5 rmdcev    GNU make C++14
#> 6 walker    C++14, GNU make      

 システム依存が多いライブラリを事前にインストールしたDockerイメージを作っておくと検証が捗るでしょう。これがtidyな形で提供されていれば言うことはありません。

パッケージを使う

 パッケージを試してみて使えそうとわかったら、自分だけが利用するのではなく他の人も活用できる仕組みを作るのと良いでしょう。
 Dockerfileに追記してイメージに反映したり、plumberやshinyなどを活用するなど様々なアプローチがありますが、本記事では時間の都合で詳しく触れません。
 shinyは近年をますます進化しているので、特に新しい情報を仕入れておく必要があります。

 googleCloudRunnerパッケージはこのあたりを良い感じにできそうで、RとGCPに詳しいどなたかの解説を期待したいところです。

 また、必要なパッケージを追加し忘れてDockerfileを書き、ビルドして気づくという体験もしばしばあると言います。
 これを避けるにはattachmentパッケージで確認すると良いでしょう。R/Rmdファイルまたは指定ディレクトリ配下のR/Rmdで呼び出しているパッケージの一覧を返す関数が定義されています。

まとめ

 本記事では、Rパッケージの情報収集を中心に検証環境の構築と利用、パッケージ活用のアプローチ例について書きました。
 Rには多種多様なパッケージがあり、探すのに苦労するだけでなく、実装後にパッケージを見つけるという事案もしばしば起こります。
 趣味でパッケージ情報を得て楽しむようなシリアルパッケージコレクター(仮)でなければ、有用なパッケージ情報が自然に集まってくるように仕組み化して気になったものだけ試すというプロセスを作ると良いでしょう。

 また、パッケージの海を泳ぐのが楽しいというタイプの方は、以下に記載したパッケージなどを試してみるのも良いかもしれません。

参考

実行環境

実行環境
sessioninfo::session_info()
#> ─ Session info ──────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 3.6.0 (2019-04-26)
#>  os       CentOS Linux 7 (Core)       
#>  system   x86_64, linux-gnu           
#>  ui       X11                         
#>  language (EN)                        
#>  collate  ja_JP.UTF-8                 
#>  ctype    ja_JP.UTF-8                 
#>  tz       UTC                         
#>  date     2019-12-18                  
#> 
#> ─ Packages ──────────────────────────────────────────────────────────────
#>  package     * version date       lib source        
#>  assertthat    0.2.1   2019-03-21 [2] CRAN (R 3.6.0)
#>  backports     1.1.4   2019-04-10 [2] CRAN (R 3.6.0)
#>  broom         0.5.2   2019-04-07 [2] CRAN (R 3.6.0)
#>  cellranger    1.1.0   2016-07-27 [2] CRAN (R 3.6.0)
#>  cli           1.1.0   2019-03-19 [2] CRAN (R 3.6.0)
#>  colorspace    1.4-1   2019-03-18 [2] CRAN (R 3.6.0)
#>  crayon        1.3.4   2017-09-16 [2] CRAN (R 3.6.0)
#>  digest        0.6.19  2019-05-20 [2] CRAN (R 3.6.0)
#>  dplyr       * 0.8.1   2019-05-14 [2] CRAN (R 3.6.0)
#>  evaluate      0.14    2019-05-28 [2] CRAN (R 3.6.0)
#>  fansi         0.4.0   2018-10-05 [2] CRAN (R 3.6.0)
#>  forcats     * 0.4.0   2019-02-17 [2] CRAN (R 3.6.0)
#>  generics      0.0.2   2018-11-29 [2] CRAN (R 3.6.0)
#>  ggplot2     * 3.1.1   2019-04-07 [2] CRAN (R 3.6.0)
#>  glue          1.3.1   2019-03-12 [2] CRAN (R 3.6.0)
#>  gtable        0.3.0   2019-03-25 [2] CRAN (R 3.6.0)
#>  haven         2.1.0   2019-02-19 [2] CRAN (R 3.6.0)
#>  highr         0.8     2019-03-20 [2] CRAN (R 3.6.0)
#>  hms           0.4.2   2018-03-10 [2] CRAN (R 3.6.0)
#>  htmltools     0.3.6   2017-04-28 [2] CRAN (R 3.6.0)
#>  httr          1.4.0   2018-12-11 [2] CRAN (R 3.6.0)
#>  jsonlite      1.6     2018-12-07 [2] CRAN (R 3.6.0)
#>  knitr         1.23    2019-05-18 [2] CRAN (R 3.6.0)
#>  lattice       0.20-38 2018-11-04 [2] CRAN (R 3.6.0)
#>  lazyeval      0.2.2   2019-03-15 [2] CRAN (R 3.6.0)
#>  lubridate     1.7.4   2018-04-11 [2] CRAN (R 3.6.0)
#>  magrittr      1.5     2014-11-22 [2] CRAN (R 3.6.0)
#>  modelr        0.1.4   2019-02-18 [2] CRAN (R 3.6.0)
#>  munsell       0.5.0   2018-06-12 [2] CRAN (R 3.6.0)
#>  nlme          3.1-139 2019-04-09 [2] CRAN (R 3.6.0)
#>  pillar        1.4.1   2019-05-28 [2] CRAN (R 3.6.0)
#>  pkgconfig     2.0.2   2018-08-16 [2] CRAN (R 3.6.0)
#>  plyr          1.8.4   2016-06-08 [2] CRAN (R 3.6.0)
#>  purrr       * 0.3.2   2019-03-15 [2] CRAN (R 3.6.0)
#>  R6            2.4.0   2019-02-14 [2] CRAN (R 3.6.0)
#>  Rcpp          1.0.1   2019-03-17 [2] CRAN (R 3.6.0)
#>  readr       * 1.3.1   2018-12-21 [2] CRAN (R 3.6.0)
#>  readxl        1.3.1   2019-03-13 [2] CRAN (R 3.6.0)
#>  remotes       2.0.2   2018-10-30 [2] CRAN (R 3.6.0)
#>  rlang         0.3.4   2019-04-07 [2] CRAN (R 3.6.0)
#>  rmarkdown     1.13    2019-05-22 [2] CRAN (R 3.6.0)
#>  rvest         0.3.4   2019-05-15 [2] CRAN (R 3.6.0)
#>  scales        1.0.0   2018-08-09 [2] CRAN (R 3.6.0)
#>  sessioninfo   1.1.1   2018-11-05 [2] CRAN (R 3.6.0)
#>  stringi       1.4.3   2019-03-12 [2] CRAN (R 3.6.0)
#>  stringr     * 1.4.0   2019-02-10 [2] CRAN (R 3.6.0)
#>  tibble      * 2.1.3   2019-06-06 [2] CRAN (R 3.6.0)
#>  tidyr       * 0.8.3   2019-03-01 [2] CRAN (R 3.6.0)
#>  tidyselect    0.2.5   2018-10-11 [2] CRAN (R 3.6.0)
#>  tidyverse   * 1.2.1   2017-11-14 [2] CRAN (R 3.6.0)
#>  utf8          1.1.4   2018-05-24 [2] CRAN (R 3.6.0)
#>  vctrs         0.1.0   2018-11-29 [2] CRAN (R 3.6.0)
#>  withr         2.1.2   2018-03-15 [2] CRAN (R 3.6.0)
#>  xfun          0.7     2019-05-14 [2] CRAN (R 3.6.0)
#>  xml2          1.2.0   2018-01-24 [2] CRAN (R 3.6.0)
#>  yaml          2.2.0   2018-07-25 [2] CRAN (R 3.6.0)
#>  zeallot       0.1.0   2018-01-28 [2] CRAN (R 3.6.0)
#> 
#> [1] /home/rstudio/R/x86_64-pc-linux-gnu-library/3.6
#> [2] /usr/local/lib64/R/library

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27