はだだだだ

定食にサラダは不要だと思う。

MENU

Rのパッケージでデータを公開する方法

nycflights13のように、Rで使用するデータをパッケージの形で保存・公開しておけば、他の人とデータを簡単に共有できます。
試行錯誤しながらとりあえずgithub上に公開するところまで出来たので、作業メモを残しておきます。

なお、本記事は以下を大いに参考にしております。

  • Rのパッケージ開発について

こわくないRパッケージ開発!2016 - Qiita

  • githubへのアップロードについて

ローカルのプロジェクトをGitHubへアップロードする方法 - Qiita

作業概要

  • 個人的に好きなNBAのデータをパッケージ化します。
  • CRANでなくgithubに公開します。
  • データ以外の関数等はパッケージに含めません。

作業環境

  • R version 3.5.1
  • R studio 1.1.453
  • Windows 7 64bit

準備

使用するデータ(csvファイル)をダウンロードします。kaggleのコンテスト用に公開されているデータです。

NBA Players stats since 1950 | Kaggle

ファイルは以下の3つです。

  • player_data.csv (選手のデータ:身長、体重、大学等)
  • Players.csv (選手のデータ:身長、体重、大学等。上とほぼ同じ)
  • Seasons_Stats.csv (選手の年毎のスタッツ)

今回は「データをパッケージにして公開する」ところがメインのためデータについての説明は割愛します。リンクのサイトからcsvファイルをダウンロードしておき、適当な場所に解凍しておきます。

併せて、githubのアカウントとパッケージを格納するrepositoryを用意します。
https://github.com/hadadada00/nbastats

パッケージの雛形作成

Rstudioのコンソールで以下を実行。

usethis::create_package("nbastats")

なお、devtools::setup()はdeprecatedのためusethis::create_package()を使いました。
実行すると、nbastatsフォルダができ、その中に以下のファイル、フォルダが作成されます。
./nbastats/
・.Rproj.user
・R
・.gitignore
・.Rbuildignore
・DESCRIPTION
・NAMESPACE
・nbastats.Rproj

併せて、データを格納するためのdataフォルダも手動で作成しておきます。
./nbastats/
・data

ここでDESCRIPTIONファイルでLasyDataがtrueになっていることを確認してください。
こうしないと、パッケージをlibrary([パッケージ名])で読んだときに、自動的にデータを全てよんでしまい、メモリを余分に使ってしまうからです。

LazyData: true

理由の詳細はこちらに記載されています。
http://r-pkgs.had.co.nz/data.html

csvファイルの読み込みとrdaファイルへの変換

csvファイルを読み込んでdataフォルダにrdaファイルとして保存します。アドホックにRスクリプトを書いて実行すればよいのですが、下記で紹介されている通り、後でデータの読み込み・保存処理を修正することを考え、使用するRスクリプト自体をパッケージに含め、一元管理できるようにします。
理由の詳細は以下です。
http://r-pkgs.had.co.nz/data.html

まず、以下のコマンドをRstudioのコンソールで実行します。

usethis::use_data_raw()

すると、data-rawフォルダが作成され、併せて、data-rawフォルダ内のファイルをビルド時に無視するよう、.Rbuildignoreの設定が変更されます。
./nbastats
・data-raw

後は、読み込み用のRスクリプトを作成し、data-rawフォルダに格納します。私は、read_csv.Rという名前にしました。
./nbastats/data-raw/read_csv.R

# TITLE : read_csv.R
# PURPOSE : read csv files and save them as .Rda files
# HISTORY : Ver.1 2019-05-15
library(readr)
library(dplyr)

# read csv files
player_data <- read_csv("../csv/player_data.csv")
players <- read_csv("../csv/Players.csv")
seasons_stats <- read_csv("../csv/Seasons_Stats.csv")

# remove unnecessary columns
players <- select(players, -X1)
seasons_stats <- select(seasons_stats, -X1)

# save as .rda files
save(player_data, file = "../data/player_data.rda")
save(players, file = "../data/players.rda")
save(seasons_stats, file = "../data/seasons_stats.rda")

パッケージのライセンス設定

Rstudioのコンソールで以下を実行します。なお、ライセンスの設定はしなくてもよいのですが、設定しないとdevtools::check()でパッケージのチェックを行ったときに、WARNINGがでます。

usethis::use_mit_license("hadadada0000")

実行すると、DESCRIPTIONファイルが以下のようになります。

License: MIT + file LICENSE

データセットの説明用ドキュメント作成

データセットの概要と変数の説明などを記載するRスクリプトを作成します。ファイルはRフォルダに格納します。ファイルはデータごとに作成するため、3種類用意します。
./nbastats/R/
・player_data.R
・players.R
・seasons_stats.R

Rドキュメントの書き方(roxygen2)は以下を参考にしました。
http://r-pkgs.had.co.nz/data.html

player_data.R
#' Datasets of NBA players since 1950
#'
#' A dataset of NBA player's profile.
#'
#' @format A data frame with 4,550 rows and 8 variables:
#' \describe{
#'   \item{name}{name}
#'   \item{year_start}{start year of the player's carrer}
#'   \item{end_year}{end year of the player's carrer}
#'   \item{position}{position of the player}
#'   \item{height}{height of the player, in ft-in}
#'   \item{weight}{weight of the player, in lb}
#'   \item{birth_date}{birth day of the player}
#'   \item{college}{college of the player}
#' }
#' @docType data
#'
#' @usage data(player_data)
#'
#' @keywords datasets
#'
#' @source \url{https://www.kaggle.com/drgilermo/nba-players-stats}
#'
"player_data"
players.R
#' Datasets of NBA players since 1950
#'
#' A dataset of NBA player's profile.
#'
#' @format A data frame with 3,922 rows and 7 variables:
#' \describe{
#'   \item{Player}{name}
#'   \item{height}{height of the player, in cm}
#'   \item{weight}{weight of the player, in kg}
#'   \item{college}{college of the player}
#'   \item{born}{born yearof the player}
#'   \item{birth_city}{birth city of the player}
#'   \item{birth_state}{birth state of the player}
#' }
#' @docType data
#'
#' @usage data(players)
#'
#' @keywords datasets
#'
#' @source \url{https://www.kaggle.com/drgilermo/nba-players-stats}
#'
"players"
seasons_stats.R
#' Datasets of NBA players' stats since 1950
#'
#' A dataset of NBA players' stats.
#'
#' @format A data frame with 24,691 rows and 52 variables:
#' \describe{
#'   \item{Year}{Year that the season occurred. Since the NBA season is split over two calendar years, the year given is the last year for that season. For example, the year for the 1999-00 season would be 2000.}
#'   \item{Player}{Name}
#'   \item{position}{Position}
#'   \item{Age}{Player age on February 1 of the given season.}
#'   \item{Tm}{Team}
#'   \item{G}{Games}
#'   \item{GS}{Games Started (available since the 1982 season)}
#'   \item{MP}{Minutes Played (available since the 1951-52 season)}
#'   \item{PER}{Player Efficiency Rating (available since the 1951-52 season), PER is a rating developed by ESPN.com columnist John Hollinger.}
#'   \item{TS\%}{True Shooting Percentage; the formula is PTS / (2 * TSA). True shooting percentage is a measure of shooting efficiency that takes into account field goals, 3-point field goals, and free throws.}
#'   \item{3PAr}{NA}
#'   \item{FTr}{NA}
#'   \item{ORB\%}{Offensive Rebound Percentage (available since the 1970-71 season in the NBA); the formula is 100 * (ORB * (Tm MP / 5)) / (MP * (Tm ORB + Opp DRB)). Offensive rebound percentage is an estimate of the percentage of available offensive rebounds a player grabbed while he was on the floor.}
#'   \item{DRB\%}{Defensive Rebound Percentage (available since the 1970-71 season in the NBA); the formula is 100 * (DRB * (Tm MP / 5)) / (MP * (Tm DRB + Opp ORB)). Defensive rebound percentage is an estimate of the percentage of available defensive rebounds a player grabbed while he was on the floor.}
#'   \item{TRB\%}{Total Rebound Percentage (available since the 1970-71 season in the NBA); the formula is 100 * (TRB * (Tm MP / 5)) / (MP * (Tm TRB + Opp TRB)). Total rebound percentage is an estimate of the percentage of available rebounds a player grabbed while he was on the floor.}
#'   \item{AST\%}{Assist Percentage (available since the 1964-65 season in the NBA); the formula is 100 * AST / (((MP / (Tm MP / 5)) * Tm FG) - FG). Assist percentage is an estimate of the percentage of teammate field goals a player assisted while he was on the floor.}
#'   \item{STL\%}{Steal Percentage (available since the 1973-74 season in the NBA); the formula is 100 * (STL * (Tm MP / 5)) / (MP * Opp Poss). Steal Percentage is an estimate of the percentage of opponent possessions that end with a steal by the player while he was on the floor.}
#'   \item{BLK\%}{Block Percentage (available since the 1973-74 season in the NBA); the formula is 100 * (BLK * (Tm MP / 5)) / (MP * (Opp FGA - Opp 3PA)). Block percentage is an estimate of the percentage of opponent two-point field goal attempts blocked by the player while he was on the floor.}
#'   \item{TOV\%}{Turnover Percentage (available since the 1977-78 season in the NBA); the formula is 100 * TOV / (FGA + 0.44 * FTA + TOV). Turnover percentage is an estimate of turnovers per 100 plays.}
#'   \item{USG\%}{Usage Percentage (available since the 1977-78 season in the NBA); the formula is 100 * ((FGA + 0.44 * FTA + TOV) * (Tm MP / 5)) / (MP * (Tm FGA + 0.44 * Tm FTA + Tm TOV)). Usage percentage is an estimate of the percentage of team plays used by a player while he was on the floor.}
#'   \item{blanl}{NA}
#'   \item{OWS}{Offensive Win Shares.} \cr
#'     \url{https://www.basketball-reference.com/about/ws.html} \cr
#'   \item{DWS}{Defensive Win Shares.} \cr
#'     \url{https://www.basketball-reference.com/about/ws.html} \cr
#'   \item{WS}{Win Shares.An estimate of the number of wins contributed by a player.} \cr
#'     \url{https://www.basketball-reference.com/about/ws.html} \cr
#'   \item{WS/48}{Win Shares Per 48 Minutes (available since the 1951-52 season in the NBA); an estimate of the number of wins contributed by the player per 48 minutes (league average is approximately 0.100). Please see the article Calculating Win Shares for more information.} \cr
#'     \url{https://www.basketball-reference.com/about/ws.html} \cr
#'   \item{blank2}{NA}
#'   \item{OBPM}{NA}
#'   \item{BPM}{Box Plus/Minus (available since the 1973-74 season in the NBA); a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team.} \cr
#'     \url{https://www.basketball-reference.com/about/bpm.html} \cr
#'   \item{VORP}{Value Over Replacement Player (available since the 1973-74 season in the NBA); a box score estimate of the points per 100 TEAM possessions that a player contributed above a replacement-level (-2.0) player, translated to an average team and prorated to an 82-game season. Multiply by 2.70 to convert to wins over replacement.} \cr
#'     \url{https://www.basketball-reference.com/about/bpm.html#vorp}
#'   \item{FG}{Field Goals (includes both 2-point field goals and 3-point field goals)}
#'   \item{FGA}{Field Goal Attempts (includes both 2-point field goal attempts and 3-point field goal attempts)}
#'   \item{FG\%}{Field Goal Percentage; the formula is FG / FGA.}
#'   \item{3P}{3-Point Field Goals (available since the 1979-80 season in the NBA)}
#'   \item{3PA}{3-Point Field Goal Attempts (available since the 1979-80 season in the NBA)}
#'   \item{3P\%}{3-Point Field Goal Percentage (available since the 1979-80 season in the NBA); the formula is 3P / 3PA.}
#'   \item{2P}{2-Point Field Goals}
#'   \item{2PA}{2-Point Field Goal Attempts}
#'   \item{2P\%}{2-Point Field Goal Percentage; the formula is 2P / 2PA.}
#'   \item{eFG\%}{Effective Field Goal Percentage; the formula is (FG + 0.5 * 3P) / FGA. This statistic adjusts for the fact that a 3-point field goal is worth one more point than a 2-point field goal. For example, suppose Player A goes 4 for 10 with 2 threes, while Player B goes 5 for 10 with 0 threes. Each player would have 10 points from field goals, and thus would have the same effective field goal percentage (50\%).}
#'   \item{FT}{Free Throws}
#'   \item{FTA}{Free Throw Attempts}
#'   \item{FT\%}{Free Throw Percentage; the formula is FT / FTA.}
#'   \item{ORB}{Offensive Rebounds (available since the 1973-74 season in the NBA)}
#'   \item{DRB}{Defensive Rebounds (available since the 1973-74 season in the NBA)}
#'   \item{TRB}{Total Rebounds (available since the 1950-51 season)}
#'   \item{AST}{Assists}
#'   \item{STL}{Steals (available since the 1973-74 season in the NBA)}
#'   \item{BLK}{Blocks (available since the 1973-74 season in the NBA)}
#'   \item{TOV}{Turnovers (available since the 1977-78 season in the NBA)}
#'   \item{PF}{Personal Fouls}
#'   \item{PTS}{Points}
#' }
#' @docType data
#'
#' @usage data(seasons_stats)
#'
#' @keywords datasets
#'
#' @source
#'   data source \cr
#'   \url{https://www.kaggle.com/drgilermo/nba-players-stats} \cr
#'   data definition \cr
#'   \url{https://www.basketball-reference.com/about/glossary.html}
"seasons_stats"

ドキュメントファイル(Rdファイル)の作成

上で作成したドキュメント用のRスクリプトを元に、Rdファイルを作成します。コンソールで以下を実行します。

devtools::document()

詳細は以下を参照
http://r-pkgs.had.co.nz/man.html

パッケージのロードとチェック

以下のコマンドをコンソールで実行し、パッケージを使用可能な状態にして動作確認をします。私の場合はtest.Rのようなファイルを作成し(パッケージには含めていません。)データが読み込めるか確認しました。

devtools::load_all()

併せて、以下のコマンドを実行し、パッケージとして不備がないか確認します。ERRORがあれば要修正、WARNINGとNOTEは内容を精査して対応します。

devtools::check()

githubへのアップロード

コマンドプロンプトを起動し、順に以下を実行します。

パッケージを格納したフォルダに移動。

cd /Users/[your name]/Desktop/Rwork/nbastats

gitリポジトリの新規作成

git init

フォルダ内の全てのファイル、フォルダをadd、commitする。

git add .
git commit -m "[your comments]"

github上のリポジトリをremoteリポジトリとして設定

git remote add origin https://github.com/hadadada00/nbastats.git

パッケージのアップロード

git push -u origin master

これでgithub上へのアップロードが完了しました。

最後に

別プロジェクトで今回作成したnbastatsパッケージを使用するときは、他のパッケージと同様に以下のコマンドで利用可能です。

パッケージのインストール

devtools::install_github("hadadada00/nbastats")

パッケージの読み込み

library(nbastats)

以上

Rパッケージ開発入門 ―テスト、文書化、コード共有の手法を学ぶ

Rパッケージ開発入門 ―テスト、文書化、コード共有の手法を学ぶ