コーディング · プログラミング言語
R言語入門:初心者向けチュートリアル
結論
Rは、統計、データ分析、グラフ作成のための無料の言語・環境です。中心となる考え方はベクトル化で、演算がベクトル全体やデータフレームの列全体に一度に適用されるため、分析コードを短く書けます。このページでは、Rのインストール、スクリプトの実行、ベクトルと型、制御構文、関数、リストとデータフレーム、統計モデル、グラフ作成、エラー処理を解説します。
Rとは何か、何に使われるのか
Rは、統計計算とグラフ作成のための無料のオープンソースの言語・環境です。ベル研究所で開発されたS言語の流れをくみ、R Core Teamによって保守されています。Rはベクトル化されており、ほとんどの演算がデータのベクトル全体に一度に作用するため、データ分析のコードを短く書けます。
Rは、統計学者、データサイエンティスト、バイオインフォマティシャン、経済学者、研究者が、データクリーニング、統計モデリング、可視化、再現可能なレポート作成に使っています。CRAN(Comprehensive R Archive Network)やBioconductorから、何千ものアドオンパッケージを入手できます。
Rのインストールとスクリプトの実行
CRANから、Windows、macOS、Linux向けのRをダウンロードします。エディタ、コンソール、プロットビューア、ヘルプペインを備えたIDEのRStudioやPositronも一緒にインストールする人が多いです。コードはRコンソールに直接入力しても、.R ファイルに保存しても構いません。
# hello.R
print("Hello, world!")
cat("Hello, world!\n")Rscript hello.R
# [1] "Hello, world!"
# Hello, world!print は、コンソールと同じ形式で、[1] というインデックスの接頭辞付きで値を表示します。cat は素のテキストを出力するので、改行は自分で付けます。
変数、基本の型、ベクトル
代入には <-(慣例的なスタイル)か = を使います。Rにはスカラーがなく、1つの数値は長さ1のベクトルです。c() は値をまとめてベクトルにし、算術演算は要素ごとに適用されます。
x <- 42 # numeric (double)
n <- 7L # integer (L suffix)
name <- "Ada" # character
ok <- TRUE # logical
class(x); class(n); class(name) # "numeric" "integer" "character"
v <- c(2, 4, 6, 8)
v * 10 # [1] 20 40 60 80
v[2] # [1] 4 (indexing starts at 1)
v[v > 4] # [1] 6 8
length(v); sum(v); mean(v) # 4 20 5
1:5 # [1] 1 2 3 4 5
seq(0, 1, by = 0.25) # [1] 0.00 0.25 0.50 0.75 1.00| 型 | 例 | 補足 |
|---|---|---|
| numeric (double) | 3.14, 42 | 数値のデフォルト |
| integer | 42L | L 接尾辞を付けた整数 |
| character | "text" | 文字列 |
| logical | TRUE, FALSE | NA は欠損値を表す |
| factor | factor(c("lo", "hi")) | 水準が固定されたカテゴリカルデータ |
制御構文
Rには、if/else、for、while、repeat があります。ベクトルに対しては、ループよりもベクトル化された ifelse() のほうが適していることが多くあります。
temp <- 25
if (temp > 30) {
print("hot")
} else if (temp > 15) {
print("mild") # [1] "mild"
} else {
print("cold")
}
for (i in 1:3) {
cat("step", i, "\n") # step 1 / step 2 / step 3
}
scores <- c(45, 80, 62)
ifelse(scores >= 50, "pass", "fail")
# [1] "fail" "pass" "pass"if には、単一の TRUE か FALSE が必要です。R 4.2以降では、長さが2以上のベクトルを if に渡すとエラーになります。代わりに any()、all()、ifelse() を使ってください。
関数
関数は function で作成し、名前に代入します。最後に評価された式が自動的に戻り値になり、return() が必要なのは途中で抜けるときだけです。引数にはデフォルト値を指定でき、名前を指定して渡せます。
bmi <- function(weight_kg, height_m = 1.75) {
weight_kg / height_m^2
}
bmi(70) # [1] 22.85714
bmi(height_m = 1.6, weight_kg = 60) # [1] 23.4375
square <- function(x) x^2
square(1:4) # [1] 1 4 9 16 (vectorized)
sapply(c(1, 4, 9), sqrt) # [1] 1 2 3
(\(x) x + 1)(10) # [1] 11 (short lambda syntax)短いラムダ構文 \(x) は、R 4.1から使えます。ネイティブパイプ |> も同様で、左辺を最初の引数として渡します。c(1, 4, 9) |> sqrt() |> sum() は6を返します。
主要なデータ構造:ベクトル、リスト、データフレーム
アトミックベクトルのほかに、Rにはリスト(異なる型の値を保持できる)、行列、データフレームがあります。データフレームは、各列が同じ長さのベクトルである表で、データ分析の中心となる構造です。
person <- list(name = "Ann", age = 31, langs = c("R", "SQL"))
person$name # [1] "Ann"
person[["langs"]][2] # [1] "SQL"
df <- data.frame(
name = c("Ann", "Bo", "Cy"),
age = c(31, 25, 40),
city = c("Oslo", "Rome", "Oslo")
)
nrow(df) # [1] 3
df$age # [1] 31 25 40
df[df$age > 30, "name"] # [1] "Ann" "Cy"
df$senior <- df$age >= 40 # add a column
aggregate(age ~ city, data = df, FUN = mean)
# city age
# 1 Oslo 35.5
# 2 Rome 25.0
str(df) # compact structure summarydf[rows, columns] は、位置、名前、論理条件で選択します。df[1, ] のように片側を空にすると、すべての行またはすべての列を意味します。
統計とグラフ作成
統計関数は標準で用意されており、summary、sd、quantile、cor、t.test、lm(線形モデル)など多数あります。基本のグラフィックスでは、1回の呼び出しでプロットを描けます。
set.seed(1)
x <- 1:20
y <- 3 * x + rnorm(20, sd = 2)
model <- lm(y ~ x)
round(coef(model), 2) # intercept near 0, slope near 3
summary(model)$r.squared # close to 1
plot(x, y, main = "y vs x")
abline(model, col = "red")数式構文 y ~ x は「yをxの関数としてモデル化する」という意味で、さまざまなモデリング関数で共通して使われます。高度なグラフやデータ整形には、install.packages("tidyverse") でggplot2やdplyrなどのtidyverseパッケージを入れるのが一般的です。
エラー処理
エラーは stop()、警告は warning() で発生させます。それらは tryCatch() で捕捉でき、error と warning のハンドラ関数と、任意の finally ブロックを渡せます。
safe_log <- function(x) {
if (!is.numeric(x)) stop("x must be numeric")
if (any(x <= 0)) warning("non-positive values give NaN or -Inf")
log(x)
}
result <- tryCatch(
safe_log("ten"),
error = function(e) {
message("Caught: ", conditionMessage(e))
NA
},
finally = message("done")
)
# Caught: x must be numeric
# done
result # [1] NA小さな完成プログラム:売上の集計
このスクリプトは、小さな売上表を作り、基本のRで地域ごとの売上を計算して、最も売上の高い地域を表示します。
sales <- data.frame(
region = c("North", "South", "North", "East", "South"),
units = c(10, 4, 6, 8, 12),
price = c(2.5, 3.0, 2.5, 4.0, 3.0)
)
sales$revenue <- sales$units * sales$price
by_region <- aggregate(revenue ~ region, data = sales, FUN = sum)
by_region <- by_region[order(-by_region$revenue), ]
print(by_region, row.names = FALSE)
# region revenue
# South 48
# North 40
# East 32
best <- by_region$region[1]
cat(sprintf("Best region: %s (%.2f)\n", best, max(by_region$revenue)))
# Best region: South (48.00)次のステップ
- CRANにある公式マニュアル「An Introduction to R」。
- 組み込みのヘルプ。コンソールで
?meanやhelp("lm")と入力します。 - Hadley Wickhamらによる「R for Data Science」。tidyverseの手法を学べる無料のオンライン書籍です。
- 計量経済学や機械学習などの分野別にパッケージを一覧できる「CRAN Task Views」。
よくある質問
データ分析にはRとPythonのどちらが向いていますか?
どちらも優れています。Rは統計手法のライブラリが豊富でグラフ作成にも優れ、学術界やバイオ統計でよく使われます。Pythonはより汎用的で、機械学習エンジニアリングで主流です。両方を学ぶアナリストも多くいます。
Rの <- と = の違いは何ですか?
どちらもトップレベルでは代入になり、<- が慣例的なスタイルです。関数呼び出しの中では = が引数の名前指定になるため、f(x = 1) は変数を作らずに引数を渡します。
Rはなぜ1から数え始めるのですか?
Rは、前身のS言語と同じく数学・統計の慣例に従っているため、ベクトルの最初の要素は v[1] です。インデックス0はエラーではなく、空のベクトルを返します。
tidyverseとは何ですか?
tidyverseは、dplyr、ggplot2、tidyrなどを含むRパッケージ群で、データの読み込み、クリーニング、変換、グラフ作成に一貫した設計を共有しています。
Rのパッケージはどうやってインストールしますか?
CRANからダウンロードするために install.packages("name") を一度実行し、セッションごとに library(name) で読み込みます。