前回,RとRStudioをインストールしました。操作に入る前に,なぜこの授業でRを使うのかを整理します。 ここが分かっていると,このあとの作業が「言われたから打つ」ではなく「何をしているか分かって打つ」になります。
この節のコードは,すべて教員が画面で実演します。入力も暗記も不要です。
rnorm(),system.time(),lm()といった関数が出てきますが,いま覚える必要はありません。 皆さんが実際に手を動かすのは,3節からです。
| 観点 | C | Python | R |
|---|---|---|---|
| 主な思想 | 汎用・計算機に近い | 汎用・可読性 | 統計計算とデータ解析 |
| 統計解析 | 自分で実装する部分が多い | ライブラリを使う | 言語環境の中心機能 |
| データ操作 | 低水準 | pandas など | data.frame / tidyverse |
| 可視化 | 自前または外部ライブラリ | matplotlib など | 標準機能+ggplot2 |
| 機械学習 | ライブラリ次第 | 非常に強い | 強い |
| 入口の学びやすさ | 急 | 比較的なだらか | 統計用途ならなだらか |
表だけでは伝わりにくいので,具体的に比べます。課題はこれです。
CSVファイルを読み込み,グループごとの平均を求め,棒グラフにする。
行動科学でデータを扱うなら,ほぼ毎回やることです。
C の場合
FILE *fp = fopen("data.csv", "r");
char line[256];
double sum[3] = {0, 0, 0};
int cnt[3] = {0, 0, 0};
while (fgets(line, sizeof(line), fp)) {
char *g = strtok(line, ","); /* 文字列を自分で切り分ける */
double v = atof(strtok(NULL, ","));
int i = group_to_index(g); /* この関数も自分で書く */
sum[i] += v;
cnt[i] += 1;
}
fclose(fp);
for (int i = 0; i < 3; i++)
printf("%d: %f\n", i, sum[i] / cnt[i]);
/* グラフは標準機能にないので,別のライブラリが必要 */Python の場合
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("data.csv")
means = df.groupby("group")["value"].mean()
means.plot(kind="bar")
plt.show()R の場合
pandas と
matplotlib
という2つのライブラリを読み込めば数行です。ライブラリが優秀です。実際,パッケージを1つも使わずにこう書けます。
誤解しないでください。Cが劣っているわけではありません。 CはOSや組み込み機器のための言語で,統計をやる道具として作られていないだけです。 PythonとRの差も,この例ではほとんどありません。
はっきり違うのは 「統計とデータ分析が,その言語の中心にあるかどうか」 です。
CもPythonも,インストールせずブラウザだけで試せます。
| 言語 | 試せる場所 |
|---|---|
| C | paiza.IO(日本語・ログイン不要) |
| C | JDoodle(ログイン不要) |
| Python | Google Colab(Googleアカウントがあれば) |
ちなみに Colab は Linux
の上で動いているので,Pythonだけの環境ではありません。
%%writefile でファイルに書き出して !gcc
を呼べば,ColabでもCが動きます。
%%writefile mean.c
#include <stdio.h>
int main(void) {
double x[] = {85, 72, 91, 68, 79};
double sum = 0;
for (int i = 0; i < 5; i++) sum += x[i];
printf("%f\n", sum / 5);
return 0;
}
!gcc mean.c -o mean && ./mean
同じ計算をRで書くと1行です。
## [1] 79
この授業で手を動かすのはRだけです。 上は「他の言語がどんなものか見てみたい人」向けの案内で,課題ではありません。
どれが優れているという話ではありません。 目的に対して道具を選びます。 この授業の目的は統計的に人間行動を分析することなので,Rを使います。
よく「C > Python > R の順に速い」と言われます。これは単純化しすぎです。
実際に,1000万個の乱数の平均を計算してみます。
## ユーザ システム 経過
## 0.020 0.003 0.022
一瞬で終わります。では,まったく同じ計算をRのループで書いてみます。
## ユーザ システム 経過
## 0.267 0.001 0.268
上の2つの「経過」を見比べてください。同じ計算でも,mean()
のほうが明確に速く終わっています(実行環境によって数値は変わります)。
理由は,mean()
の中身がRで書かれていないからです。重い計算は,コンパイル済みのネイティブコード(CやFortran)側で動いています。
「何の言語で書いたか」と「実際にどこで計算しているか」は別の問題です。
Pythonでも同じで,
numpyの処理とPythonのforループは別物です。
いま見たのは 「Rの
mean()」と「Rで書いたループ」の比較です。ここから言えるのは,次の一点です。
同じ目的の計算でも,どう書くかで速度が変わる。
一方,この実演だけでは次のことは言えません。
「Rは遅い」という評判はよく聞きますが,その多くはループを自分で書いた場合の話です。統計解析で実際に使うのは
mean() や lm()
のような関数で,その中身はコンパイル済みのコードで動きます。ですから「Rは遅いから使わない」という判断は,少なくともこの授業の用途では当たりません。
そして mean()
を使う本当の理由は,速いことよりも「何をしたいかがそのまま書ける」ことにあります。
次の1-3がその話です。
同じ「平均を求める」を書き比べます。Cなら,考え方としてはこうです。
Rならこうです。
Cは計算機が実際に何をしているかに近い書き方です。 Rは「このデータの平均が欲しい」と宣言している書き方です。
これは難しい・易しいの差ではなく,抽象化のレベルの差です。
行動計量学で知りたいのは,メモリの中身やループの実装ではありません。たとえば
\[Y_i = \beta_0 + \beta_1 X_i + \epsilon_i\]
の \(\beta_1\) がどう推定されるか,です。だから
と書けばよい。Cで最小二乗法を一から実装することには計算機科学としての意味がありますが,この授業では目的と手段が逆転してしまいます。
R 言語 + 統計計算環境 … 実際に計算しているのはこちら
RStudio Rを操作するためのIDE … 画面を使いやすくまとめたもの
前回入れたのは,この2つです。ひとつのソフトではありません。
皆さんが前回入れたRStudioが計算しているわけではありません。計算しているのはRです。
RStudioは,スクリプト・コンソール・グラフ・ファイルを1つの画面にまとめ,全員の作業環境をそろえるために使います。
Rには後から機能を足せます。その単位がパッケージです。
| 用語 | たとえると |
|---|---|
| R本体 | 作業場+基本の道具 |
| パッケージ | あとから追加できる道具箱 |
| 関数 | 道具箱の中の個々の道具 |
| CRAN | 道具箱を集めて配布している公式の倉庫 |
CRAN(シーラン)は Comprehensive R Archive Network
の略です。一定の形式的なチェックを通ったRパッケージを配布しているリポジトリで,install.packages()
は原則ここから持ってきます。
このチェックは,パッケージが決まった形式で正しく動くかという技術的な確認です。 そのパッケージが出す統計的な結果の正しさまで保証するものではありません。
GitHubと似ていますが別物です。GitHubはソースコードを管理・共同開発する場所,CRANは審査を通ったパッケージを配布する場所です。
この区別が,最初につまずきやすい install.packages() と
library() の違いにそのまま対応します。
| コード | たとえると | 頻度 |
|---|---|---|
install.packages("ggplot2") |
倉庫から道具箱を買って作業場に置く | 原則1回だけ |
library(ggplot2) |
その道具箱を棚から出して開く | Rを起動するたび |
実際のコードは第6節で扱います。
tidyverse(タイディバース)は
tidy(整然とした)+ universe の造語です。
ここでの tidy は「きれい」ではなく,tidy
data(整然データ) という考え方を指します。
という構造です。
tidyverseは,この考え方を共有するパッケージ群の総称です。
| パッケージ | 役割 |
|---|---|
ggplot2 |
可視化 |
dplyr |
データの整形・加工 |
tidyr |
データの形を整える(縦持ち・横持ちの変換など) |
readr |
データの読み込み |
tidyverse = データを「整った形」で扱うという共通の思想をもったRの道具箱セット
第1回の授業内でRとRStudioを入れました。まず,全員の環境が動くことを確認します。
RStudioを起動し,Console に次を1行ずつ入力して
Enter を押してください。
バージョン番号が表示され,[1] 2
と出れば問題ありません。
今日この場で解決します。遠慮なく手を挙げてください。手順書は下記にあります。
→ R・RStudioのインストール手順(作成:TA 齋藤悠輔さん)
どうしてもインストールできない場合は,ブラウザの中でRStudioが動く Posit Cloud で授業に参加できます。
New Project → New RStudio Project無料プランには1か月あたりの利用時間の上限があります。「インストールできるまでの避難先」として使ってください。 この授業の到達目標の1つは「自力で分析環境を構築できる」ことなので,落ち着いたら改めて挑戦しましょう。個別に相談に応じます。
┌──────────────────────────┬──────────────────────┐
│ ① スクリプトエディタ │ ② 環境・履歴パネル │
│ .R ファイルを書く場所 │ 変数・データを確認 │
│ │ │
├──────────────────────────┼──────────────────────┤
│ ③ コンソール │ ④ ファイル・プロット │
│ コードを直接実行できる │ グラフ・ヘルプ等 │
│ 出力結果が表示される │ │
└──────────────────────────┴──────────────────────┘
| パネル | 役割 | よく使う機能 |
|---|---|---|
| ① スクリプト | コードを書いて保存する | Ctrl+Enter で実行 |
| ② 環境 | 作成した変数を一覧表示 | データの中身を確認 |
| ③ コンソール | 実行結果が表示される | 直接入力も可能 |
| ④ プロット | グラフが表示される | Zoom で拡大 |
起動直後は左上のスクリプトエディタが表示されていないことがあります。 次の手順でスクリプトを1つ作ると現れます。
今日の作業は,すべてこのスクリプトに書いていきます。 先に作ってしまいましょう。
File → New File →
R Script1 + 1 と書くCtrl + Enter(Macは
Cmd + Enter) → 下のコンソールに [1] 2
と出れば成功ですCtrl + S(Macは
Cmd + S)で保存。ファイル名は
第02回_練習.R保存先を決めておいてください。
Ctrl + Sを初めて押したときだけ,保存先を聞く画面が出ます(2回目以降は同じ場所に上書きされます)。 ここで流されるままデスクトップや「ダウンロード」に入れてしまうと,次回ファイルを見つけられません。この授業用のフォルダを1つ決めて,そこに入れてください。 例:「ドキュメント」の中に
kodo-keiryoというフォルダを作る。 フォルダ名は半角英数字にしておくと,のちのちトラブルが少なくなります。保存できたかは,RStudioの右下の
Filesタブで確認できます。 置き場所のより良い整え方(プロジェクト)は, 第3回の0-1で説明します。
コンソールに直接打ったものは保存されません。 スクリプトに書いて実行すれば,コードが手元に残り,あとから同じ分析をやり直せます。 以降の4節・5節のコードも,このスクリプトに書き足していってください。
コードを実行する前に,コンソールに現れる記号を確認しておきます。
| 記号 | 意味 |
|---|---|
> |
入力待ちの印。自分では打ちません |
[1] |
結果の表示。その行の先頭が1番目の要素であることを示す |
## |
この資料で「これは実行結果です」と示すための印。打ちません |
+ |
入力が終わっていない合図。 括弧や引用符が閉じていません |
+ が出て先に進めなくなったら,Esc
キーで取り消して書き直してください。
括弧
( ),引用符" ",演算子はすべて半角で入力します。 全角で入力するとエラーになります。日本語入力をオフにしてから打ってください。
## [1] 8
## [1] 6
## [1] 42
## [1] 3.75
## [1] 8
## [1] 2
#から始まる行はコメントです。Rは実行しません。 コードに説明を書くために使います。
## [1] 10
## [1] 20
## [1] 15
Rでは
<-を代入演算子として使います(=でも動きますが,<-が慣例)。
よくあるつまずき
x <- 10を実行しても何も表示されません。これは正常です。中身を見たいときはxだけを実行します。y <- x + 5は,その時点のxの値で計算した結果をyに入れる操作です。 あとからxを変えてもyは自動では変わりません。y <- x + 5の行をもう一度実行してから,yを表示してください。- スクリプトを書き換えただけでは,何も計算されません。実行して初めて値が変わります。
## [1] "小野原"
## [1] "こんにちは, 小野原 さん"
## [1] 85 72 91 68 79
## [1] 5
## [1] 395
## [1] 79
## [1] 68
## [1] 91
Rの命令は,いくつかの部品でできています。average <- mean(scores)
を分解してみます。
Pythonを触ったことがある人のために,同じ処理をPythonで書いたものを並べます。
R average <- mean( scores )
Python average = mean( scores )
│ │ │ │
│ │ │ └─ 引数(ひきすう):処理したいデータ
│ │ └──────── 関数名:何をするか
│ └────────────── 代入:右の結果を左の名前に入れる
└──────────────────── オブジェクト(変数):結果につける名前
部品の並びも役割も,Pythonとまったく同じです。違うのは代入の記号が
<- か = かだけ。 「= が
<- に変わっただけ」と考えて構いません。
| 部分 | 呼び方 | 意味 | Pythonでは |
|---|---|---|---|
average |
オブジェクト(変数) | 結果につける名前 | 同じ |
<- |
代入演算子 | 右の結果を左の名前に入れる | = |
mean |
関数名 | 何をするかの名前 | 同じ(下記参照) |
scores |
引数(ひきすう) | 処理したいデータ | 同じ |
79 |
返り値 | 返ってくる結果 | 同じ |
この形を覚えてしまえば,関数が mean から sd
や summary に変わっても, データが scores
から別のものに変わっても,読み方は同じです。
なぜ
=ではなく<-なのかRでも
average = mean(scores)と書けば動きます。それでも<-を使うのは, Rでは=を関数の引数に名前をつけるときに使うからです。記号を分けておくと,代入なのか引数の指定なのかが一目で分かります。
「最初から使えるか」は違います
Pythonで
mean()を使うにはimport statisticsやimport numpyが要ります。 Rはmean()もsd()も最初から使えます。1-1で見た「統計がR本体に入っている」の一例です。
## [1] 79
代入しない場合との違い
mean(scores)だけを実行すると,結果が画面に出るだけで消えます。average <- mean(scores)とすると,結果がaverageに残り,あとで使い回せます。
関数の使い方を調べたいときは
?meanと打つとヘルプが開きます。
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 10.00 12.25 14.50 14.60 16.75 20.00
## [1] 14.6
## [1] 14.5
## [1] 3.204164
## [1] 10.26667
分母に注意してください。
Rの
var()は,分母が データ数より1少ない(\(n-1\))分散を返します。sd()はその平方根です。 高校までに分母 \(n\) の式を習った人は,手計算と値が合わないことがあります。 この授業では,分散・標準偏差は原則としてvar()・sd()で求めます。
summary()
の出力は英語なので,対応を確認しておきます。
| 表示 | 意味 |
|---|---|
Min. |
最小値 |
1st Qu. |
第1四分位数 |
Median |
中央値 |
Mean |
平均値 |
3rd Qu. |
第3四分位数 |
Max. |
最大値 |
四分位数の求め方には複数の流儀があり,手計算の方法によっては値が少しずれます。 ここではRの標準設定をそのまま使います。
パッケージは,Rの機能を拡張するためのツールセットです。
インストール(
install.packages())は,そのPCで1回だけでOK。 読み込み(library())はRを起動するたびに必要です。ただし「1回だけ」は同じPC・同じRについての話です。別のPCを使うときや,Rを新しくしたときは入れ直しが要ります。
library(tidyverse)
を実行すると,次のようなメッセージが出ます。
── Attaching core tidyverse packages ──
✔ dplyr 1.1.4 ✔ readr 2.1.5 ...
── Conflicts ──
✖ dplyr::filter() masks stats::filter()
これはエラーではありません。 Conflicts
や masks
は「同じ名前の関数が複数あるので,こちらを優先します」という案内です。読み込みは成功しています。
ただし,警告(Warning)の中には,インストールの失敗を知らせるものもあります。
例えばインストールが途中で失敗すると non-zero exit status
という警告が出ます。「警告ならすべて無視してよい」わけではありません。
判断の基準はこれです。
library(tidyverse)が実行できるかどうか。
実行してエラーにならなければ大丈夫です。実行できない場合や,表示の意味が分からない場合は,メッセージを消さずに呼んでください。
今日の演習1〜3に tidyverse は使いません。 Rさえ動いていれば演習は進められます。インストールがうまくいかなくても,そこで止まらずに先へ進んでください。
3節で作ったスクリプトの,操作のまとめです。
| 操作 | Windows | Mac |
|---|---|---|
| カーソルの行を実行 | Ctrl + Enter |
Cmd + Enter |
| 選択範囲を実行 | 選択して Ctrl + Enter |
選択して Cmd + Enter |
| スクリプト全体を実行 | Ctrl + Shift + Enter |
Cmd + Shift + Enter |
| 保存 | Ctrl + S |
Cmd + S |
「全体を実行したのに,結果が表示されない」とき
選択範囲の実行は,その行がそのままコンソールに打ち込まれます。だから自分で打ったときと同じように結果が出ます。 一方の全体実行(Source)は,ファイルをいったん保存してから読み込む別の経路を通るため,設定によっては計算結果が自動表示されません。
すべての結果を確認したいときは,スクリプトを全選択して
Ctrl + Enter(MacはCmd + Enter)で実行してください。 全体実行で特定の値を表示させたい場合は,print(bmi)のように明示的に書きます。
この授業の標準の進め方
資料のHTML版を読みながら,コードは自分の
.Rファイルに書いて実行します。 サイトにはRmd版も置いてありますが,そちらを使うかどうかは任意です。
ファイルをどこに置くか(プロジェクト)と, RStudioを閉じるときに出る「Save workspace image to ~/.RData?」の意味は, 第3回の資料にまとめてあります。
3節で作ったスクリプトに書いて実行しましょう。
下の3行はコメントなので,そのまま実行しても何も起こりません。各問題の下に,自分で計算式を書いてください。
下の架空のデータを使って,BMIを計算してください。
___
は数値を入れるための空欄です。そのまま実行するとエラーになります。
\[\text{BMI} = \frac{\text{体重(kg)}}{\left(\text{身長(m)}\right)^2}\]
# 架空の人物A:身長 160 cm,体重 60 kg
height_cm <- ___ # 160 を入れる
weight_kg <- ___ # 60 を入れる
height_m <- height_cm / 100
bmi <- weight_kg / height_m^2
bmi追加問題:体重だけを 65 kg に変えて,BMIを計算し直してください。
weight_kgの行を書き換えただけでは,bmiは変わりません。weight_kg以降の行をもう一度実行する必要があります。これが4-2節で確認したことです。
# ある授業の小テストの点数(架空データ)
quiz_scores <- c(65, 78, 82, 55, 90, 71, 68, 85, 77, 60)
# 以下を計算してください
# 1. 平均点 → mean()
# 2. 最高点と最低点 → max(), min()
# 3. 標準偏差 → sd() を使うこと標準偏差は
sd()で求めてください(分母は \(n-1\))。 分母 \(n\) で手計算すると別の値になります。値を文章で書くときは小数第2位まででかまいません。
次の2つを,それぞれ1文で説明してください。コードは不要です。
install.packages() と library()
の違い回答は,各行の先頭に #
を付けて,同じスクリプトに書いてください。 #
のない文章を書くとエラーになります。
演習1〜4の解答例を置いてあります。自分で解いたあとに見てください。
ブラウザで中身が表示されます。保存するときは右クリック →「リンク先を別名で保存」。 RStudioで開いて,上から順に実行して確かめてください。
install.packages()
は原則1回,library() は起動ごと.R
ファイルにまとめて保存し,次回の授業で開ける状態にしておく
.R
ファイルを開き直し,上から順にコードを実行して,同じ結果が得られることCtrl + Enter(Macは Cmd + Enter)。
全部を確かめたいときは全選択して
Ctrl + Enter ですsource("ファイル名.R") や Source
ボタンでまとめて実行すると,
計算結果が表示されないことがあります(7節参照)。
まとめて実行して値を見たいときは print(bmi)
のように書いてくださいlibrary(tidyverse)
が実行できることを確認しておく
install.packages("tidyverse")
から