R

#15
TIOBE#14
PYPL#6
GitHub#34
RedMonk#12
IEEESpectrum#20
プログラミング言語統計計算データ分析機械学習データサイエンス可視化

プログラミング言語

R

概要

Rは統計計算とデータ分析に特化したプログラミング言語です。

詳細

Rは1993年にロス・イハカとロバート・ジェントルマンによってニュージーランドで開発された統計計算とグラフィックス作成のためのプログラミング言語・環境です。S言語の実装として始まり、統計解析、データマイニング、機械学習、データ可視化に特化した豊富な機能を提供しています。CRAN(The Comprehensive R Archive Network)には20,000以上のパッケージが登録されており、あらゆる統計手法やデータ分析手法に対応可能です。学術研究、データサイエンス、バイオインフォマティクス、金融分析などの分野で広く使用されており、統計学者やデータサイエンティストにとって必須のツールとなっています。

書き方の例

Hello World

# 基本的な出力
print("Hello, World!")

# cat関数を使った出力
cat("Hello, R!\n")

# 変数を使った出力
message <- "こんにちは、R!"
print(message)

# 複数の値を出力
name <- "太郎"
age <- 25
cat("私の名前は", name, "で、", age, "歳です。\n")

# paste関数を使った文字列結合
greeting <- paste("Hello,", "R", "Programming!")
print(greeting)

# sprintf関数を使ったフォーマット
formatted_message <- sprintf("私の名前は%sで、%d歳です。", name, age)
print(formatted_message)

変数とデータ型

# 数値型
x <- 42
y <- 3.14159
scientific_notation <- 1.23e-4

# 文字列型
name <- "田中太郎"
city <- '東京'

# 論理型
is_active <- TRUE
is_complete <- FALSE

# 因子型(カテゴリカルデータ)
gender <- factor(c("男性", "女性", "男性", "女性"))
print(levels(gender))

# ベクトル(同じ型の要素の集合)
numbers <- c(1, 2, 3, 4, 5)
fruits <- c("りんご", "バナナ", "オレンジ")
logicals <- c(TRUE, FALSE, TRUE)

# 数列の生成
sequence1 <- 1:10  # 1から10まで
sequence2 <- seq(0, 100, by=10)  # 0から100まで10刻み
repeated <- rep(c(1, 2), times=5)  # 1,2を5回繰り返し

# リスト(異なる型の要素を含む)
person <- list(
  name = "山田花子",
  age = 30,
  married = TRUE,
  children = c("太郎", "花子")
)

# データフレーム(表形式データ)
df <- data.frame(
  名前 = c("田中", "山田", "佐藤"),
  年齢 = c(25, 30, 35),
  性別 = c("男性", "女性", "男性"),
  stringsAsFactors = FALSE
)

# 行列
matrix1 <- matrix(1:12, nrow=3, ncol=4)
matrix2 <- matrix(c(1,2,3,4,5,6), nrow=2, byrow=TRUE)

# 配列(多次元)
array1 <- array(1:24, dim=c(2,3,4))

# データ型の確認
print(class(x))          # "numeric"
print(class(name))       # "character"  
print(class(is_active))  # "logical"
print(class(df))         # "data.frame"

# データ構造の情報
str(person)  # リストの構造
str(df)      # データフレームの構造
summary(df)  # データの要約統計

# 型変換
number_as_char <- as.character(42)
char_as_number <- as.numeric("123")
number_as_logical <- as.logical(c(0, 1, 2))

print(paste("数値→文字:", number_as_char))
print(paste("文字→数値:", char_as_number))
print(paste("数値→論理:", number_as_logical))

関数とコントロール構造

# 基本的な関数定義
add_numbers <- function(a, b) {
  result <- a + b
  return(result)
}

# デフォルト引数付きの関数
greet <- function(name, greeting = "こんにちは") {
  message <- paste(greeting, name, "さん!")
  return(message)
}

# 可変長引数
calculate_stats <- function(...) {
  values <- c(...)
  list(
    平均 = mean(values),
    中央値 = median(values),
    標準偏差 = sd(values),
    最小値 = min(values),
    最大値 = max(values)
  )
}

# 条件分岐 - if文
age <- 20
if (age >= 18) {
  print("成人です")
} else {
  print("未成年です")
}

# 複数条件
score <- 85
if (score >= 90) {
  grade <- "A"
} else if (score >= 80) {
  grade <- "B"
} else if (score >= 70) {
  grade <- "C"
} else {
  grade <- "D"
}
print(paste("成績:", grade))

# ifelse関数(ベクトル化された条件分岐)
ages <- c(15, 22, 17, 30, 16)
status <- ifelse(ages >= 18, "成人", "未成年")
print(status)

# switch文
get_day_name <- function(day_number) {
  switch(day_number,
    "1" = "月曜日",
    "2" = "火曜日", 
    "3" = "水曜日",
    "4" = "木曜日",
    "5" = "金曜日",
    "6" = "土曜日",
    "7" = "日曜日",
    "無効な日"
  )
}

# for文
print("=== for文の例 ===")
for (i in 1:5) {
  print(paste("カウント:", i))
}

# ベクトルでのfor文
fruits <- c("りんご", "バナナ", "オレンジ")
for (fruit in fruits) {
  print(paste("フルーツ:", fruit))
}

# while文
count <- 1
while (count <= 3) {
  print(paste("while文 カウント:", count))
  count <- count + 1
}

# repeat文(無限ループ)
counter <- 1
repeat {
  print(paste("repeat文 カウント:", counter))
  counter <- counter + 1
  if (counter > 3) {
    break
  }
}

# 関数の呼び出し例
print(add_numbers(5, 3))
print(greet("田中"))
print(greet("山田", "おはよう"))

stats <- calculate_stats(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(stats)

for (day in 1:7) {
  print(get_day_name(as.character(day)))
}

データ操作と分析

# サンプルデータの作成
set.seed(123)  # 再現性のための乱数シード設定
n <- 100

# データフレームの作成
students <- data.frame(
  学生ID = 1:n,
  名前 = paste0("学生", 1:n),
  数学 = round(rnorm(n, mean=75, sd=15), 1),
  英語 = round(rnorm(n, mean=70, sd=12), 1),
  理科 = round(rnorm(n, mean=78, sd=18), 1),
  性別 = factor(sample(c("男性", "女性"), n, replace=TRUE)),
  学年 = factor(sample(1:3, n, replace=TRUE)),
  stringsAsFactors = FALSE
)

# データの基本情報
print("=== データの基本情報 ===")
print(head(students))          # 最初の6行
print(tail(students))          # 最後の6行
print(dim(students))           # 行数と列数
print(nrow(students))          # 行数
print(ncol(students))          # 列数
print(colnames(students))      # 列名
print(summary(students))       # 要約統計

# データの選択・抽出
print("=== データの選択 ===")
# 特定の列を選択
math_scores <- students$数学
english_scores <- students[, "英語"]
selected_columns <- students[, c("名前", "数学", "英語")]

# 特定の行を選択
first_10_students <- students[1:10, ]
specific_student <- students[students$学生ID == 5, ]

# 条件による抽出
high_math_students <- students[students$数学 >= 80, ]
male_students <- students[students$性別 == "男性", ]
excellent_students <- students[students$数学 >= 80 & students$英語 >= 80, ]

print(paste("数学80点以上の学生数:", nrow(high_math_students)))
print(paste("男性学生数:", nrow(male_students)))
print(paste("数学・英語ともに80点以上の学生数:", nrow(excellent_students)))

# データの変更・追加
students$合計点 <- students$数学 + students$英語 + students$理科
students$平均点 <- round(students$合計点 / 3, 1)

# 成績評価の追加
students$評価 <- cut(students$平均点, 
                    breaks = c(0, 60, 70, 80, 90, 100),
                    labels = c("D", "C", "B", "A", "S"),
                    include.lowest = TRUE)

# 基本統計量の計算
print("=== 基本統計量 ===")
cat("数学の平均:", mean(students$数学), "\n")
cat("数学の中央値:", median(students$数学), "\n")
cat("数学の標準偏差:", sd(students$数学), "\n")
cat("数学の分散:", var(students$数学), "\n")
cat("数学の最小値:", min(students$数学), "\n")
cat("数学の最大値:", max(students$数学), "\n")

# グループ別集計
print("=== グループ別集計 ===")
# 性別ごとの平均点
gender_avg <- aggregate(平均点 ~ 性別, data = students, FUN = mean)
print(gender_avg)

# 学年ごとの科目別平均
grade_avg <- aggregate(cbind(数学, 英語, 理科) ~ 学年, data = students, FUN = mean)
print(grade_avg)

# 評価別の人数
evaluation_count <- table(students$評価)
print(evaluation_count)

# 性別×学年のクロス集計
cross_table <- table(students$性別, students$学年)
print(cross_table)

# 相関分析
print("=== 相関分析 ===")
numeric_columns <- students[, c("数学", "英語", "理科")]
correlation_matrix <- cor(numeric_columns)
print(correlation_matrix)

データ可視化

# 基本的なプロット
print("=== 基本プロット(データ可視化)===")

# データの準備(前のセクションのstudentsデータを使用)
# 注意: 実際のRコンソールでは以下のplot関数でグラフが表示されます

# 散布図
plot(students$数学, students$英語, 
     main = "数学と英語の散布図",
     xlab = "数学の点数", 
     ylab = "英語の点数",
     col = "blue",
     pch = 16)

# 回帰直線の追加
abline(lm(英語 ~ 数学, data = students), col = "red", lwd = 2)

# ヒストグラム
hist(students$数学, 
     main = "数学の点数分布",
     xlab = "点数", 
     ylab = "頻度",
     col = "lightblue",
     breaks = 20)

# 箱ひげ図
boxplot(数学 ~ 性別, data = students,
        main = "性別ごとの数学の点数分布",
        xlab = "性別",
        ylab = "数学の点数",
        col = c("pink", "lightblue"))

# 棒グラフ
barplot(table(students$評価),
        main = "評価別学生数",
        xlab = "評価",
        ylab = "人数",
        col = rainbow(5))

# ggplot2を使った高度な可視化
# install.packages("ggplot2")  # 初回のみ必要
library(ggplot2)

# 散布図(ggplot2)
p1 <- ggplot(students, aes(x = 数学, y = 英語, color = 性別)) +
  geom_point(size = 2, alpha = 0.7) +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "数学と英語の関係(性別別)",
       x = "数学の点数", 
       y = "英語の点数") +
  theme_minimal()

# ヒストグラム(ggplot2)
p2 <- ggplot(students, aes(x = 平均点, fill = 性別)) +
  geom_histogram(bins = 20, alpha = 0.7, position = "identity") +
  facet_wrap(~性別) +
  labs(title = "平均点の分布(性別別)",
       x = "平均点",
       y = "頻度") +
  theme_minimal()

# 箱ひげ図(ggplot2)
p3 <- ggplot(students, aes(x = 学年, y = 平均点, fill = 学年)) +
  geom_boxplot(alpha = 0.7) +
  geom_jitter(width = 0.2, alpha = 0.5) +
  labs(title = "学年別平均点の分布",
       x = "学年",
       y = "平均点") +
  theme_minimal()

# 注意: 実際にグラフを表示するには以下のコマンドを実行
# print(p1)
# print(p2) 
# print(p3)

print("グラフ作成コードを実行しました。実際のRコンソールではグラフが表示されます。")

統計分析

# 記述統計
print("=== 記述統計 ===")

# 基本統計量の詳細
desc_stats <- function(x) {
  list(
    平均 = mean(x, na.rm = TRUE),
    中央値 = median(x, na.rm = TRUE),
    最頻値 = as.numeric(names(sort(table(x), decreasing = TRUE))[1]),
    標準偏差 = sd(x, na.rm = TRUE),
    分散 = var(x, na.rm = TRUE),
    最小値 = min(x, na.rm = TRUE),
    最大値 = max(x, na.rm = TRUE),1四分位 = quantile(x, 0.25, na.rm = TRUE),3四分位 = quantile(x, 0.75, na.rm = TRUE),
    歪度 = moments::skewness(x, na.rm = TRUE),
    尖度 = moments::kurtosis(x, na.rm = TRUE)
  )
}

# 数学の記述統計
# install.packages("moments")  # 初回のみ必要
library(moments)
math_stats <- desc_stats(students$数学)
print("数学の記述統計:")
print(math_stats)

# 仮説検定
print("=== 仮説検定 ===")

# 1. 一標本t検定(数学の平均が75と有意に異なるか)
t_test_one <- t.test(students$数学, mu = 75)
print("一標本t検定(数学の平均 vs 75):")
print(t_test_one)

# 2. 二標本t検定(男女の数学の平均に差があるか)
male_math <- students[students$性別 == "男性", "数学"]
female_math <- students[students$性別 == "女性", "数学"]

t_test_two <- t.test(male_math, female_math)
print("二標本t検定(男女の数学の平均の差):")
print(t_test_two)

# 3. 対応のあるt検定(数学と英語の平均に差があるか)
paired_t_test <- t.test(students$数学, students$英語, paired = TRUE)
print("対応のあるt検定(数学 vs 英語):")
print(paired_t_test)

# 4. カイ二乗検定(性別と評価の独立性)
chi_square_test <- chisq.test(table(students$性別, students$評価))
print("カイ二乗検定(性別と評価の独立性):")
print(chi_square_test)

# 5. 分散分析(ANOVA)- 学年間の平均点の差
anova_result <- aov(平均点 ~ 学年, data = students)
print("分散分析(学年間の平均点):")
print(summary(anova_result))

# 事後検定(Tukey HSD)
tukey_result <- TukeyHSD(anova_result)
print("Tukey HSD事後検定:")
print(tukey_result)

# 相関検定
print("=== 相関分析 ===")

# ピアソンの相関係数
cor_test_math_english <- cor.test(students$数学, students$英語)
print("数学と英語の相関検定:")
print(cor_test_math_english)

# スピアマンの順位相関
cor_test_spearman <- cor.test(students$数学, students$英語, method = "spearman")
print("数学と英語のスピアマン相関:")
print(cor_test_spearman)

# 正規性検定
print("=== 正規性検定 ===")

# シャピロ・ウィルク検定
shapiro_math <- shapiro.test(students$数学)
print("数学の正規性検定(Shapiro-Wilk):")
print(shapiro_math)

# コルモゴロフ・スミルノフ検定
ks_math <- ks.test(students$数学, "pnorm", mean = mean(students$数学), sd = sd(students$数学))
print("数学の正規性検定(Kolmogorov-Smirnov):")
print(ks_math)

# 回帰分析
print("=== 回帰分析 ===")

# 単回帰分析
simple_regression <- lm(英語 ~ 数学, data = students)
print("単回帰分析(英語 ~ 数学):")
print(summary(simple_regression))

# 重回帰分析
multiple_regression <- lm(平均点 ~ 数学 + 英語 + 理科, data = students)
print("重回帰分析(平均点 ~ 数学 + 英語 + 理科):")
print(summary(multiple_regression))

# 回帰診断
par(mfrow = c(2, 2))
plot(simple_regression)
par(mfrow = c(1, 1))

print("統計分析が完了しました。")

パッケージ管理とデータ入出力

# パッケージ管理
print("=== パッケージ管理 ===")

# インストール済みパッケージの確認
installed_packages <- installed.packages()[, c("Package", "Version")]
print(paste("インストール済みパッケージ数:", nrow(installed_packages)))

# パッケージのインストール(例)
# install.packages("dplyr")
# install.packages("ggplot2")
# install.packages("readr")

# パッケージの読み込み
library(utils)  # 基本パッケージ

# パッケージが読み込まれているかチェック
search()  # 読み込み済みパッケージの表示

# データ入出力
print("=== データ入出力 ===")

# CSVファイルの読み書き
# データの保存
write.csv(students, "students_data.csv", row.names = FALSE, fileEncoding = "UTF-8")
print("CSVファイルに保存しました: students_data.csv")

# データの読み込み
# loaded_data <- read.csv("students_data.csv", fileEncoding = "UTF-8")
# print("CSVファイルから読み込み完了")

# Excelファイルの読み書き(openxlsxパッケージ使用)
# install.packages("openxlsx")  # 初回のみ
# library(openxlsx)
# write.xlsx(students, "students_data.xlsx")
# loaded_excel <- read.xlsx("students_data.xlsx")

# RDataファイル(Rネイティブ形式)
save(students, file = "students_data.RData")
print("RDataファイルに保存しました: students_data.RData")

# load("students_data.RData")  # データの読み込み

# テキストファイルの読み書き
writeLines(c("これはテストファイルです", "2行目のデータ", "3行目のデータ"), "test.txt")
text_data <- readLines("test.txt", encoding = "UTF-8")
print("テキストファイルの内容:")
print(text_data)

# JSONファイルの読み書き(jsonliteパッケージ)
# install.packages("jsonlite")  # 初回のみ
# library(jsonlite)

# リストをJSONに変換
sample_list <- list(
  name = "サンプルデータ",
  values = c(1, 2, 3, 4, 5),
  metadata = list(
    created = Sys.Date(),
    author = "R script"
  )
)

# json_string <- toJSON(sample_list, pretty = TRUE, auto_unbox = TRUE)
# writeLines(json_string, "sample_data.json")
# loaded_json <- fromJSON("sample_data.json")

# URLからデータを読み込み(例:CSV)
# url_data <- read.csv("https://example.com/data.csv")

# データベース接続(例:SQLite)
# install.packages("RSQLite")  # 初回のみ
# library(RSQLite)
# 
# # データベース接続
# con <- dbConnect(SQLite(), "sample.db")
# 
# # データをデータベースに書き込み
# dbWriteTable(con, "students", students, overwrite = TRUE)
# 
# # SQLクエリでデータ取得
# query_result <- dbGetQuery(con, "SELECT * FROM students WHERE 数学 > 80")
# 
# # 接続を閉じる
# dbDisconnect(con)

# 作業ディレクトリの確認・変更
print(paste("現在の作業ディレクトリ:", getwd()))

# ファイル一覧の表示
files_in_dir <- list.files()
print("現在のディレクトリのファイル:")
print(files_in_dir)

# ファイルの存在確認
print(paste("students_data.csv exists:", file.exists("students_data.csv")))
print(paste("students_data.RData exists:", file.exists("students_data.RData")))

# ファイルサイズの確認
if (file.exists("students_data.csv")) {
  file_size <- file.size("students_data.csv")
  print(paste("students_data.csvのサイズ:", file_size, "bytes"))
}

print("パッケージ管理とデータ入出力の例が完了しました。")

バージョン

バージョン リリース日 主な新機能
R 4.4 2024-04 Performance improvements, Enhanced object.size()
R 4.3 2023-04 Improved graphics engine, New shorthand syntax
R 4.2 2022-04 Graphics improvements, Enhanced pipe operator
R 4.1 2021-05 Native pipe operator, Improved graphics
R 4.0 2020-04 Reference counting, Raw strings
R 3.6 2019-04 Serialization improvements, Better random number generation

参考ページ

公式ドキュメント

学習リソース

パッケージ・ツール

  • RStudio - R開発環境IDE
  • Tidyverse - データサイエンス用パッケージ群
  • Shiny - インタラクティブWebアプリ作成
  • ggplot2 - データ可視化パッケージ