はじめに
- Rに関する役立つ情報を随時追記していく
ライブラリ メモ
plyr
- データ操作を簡略化する関数が多数用意されている便利パッケージ
- slideshare(plyrパッケージで君も前処理スタ)
reshape2
- データ変形ツール
- 「ggplot2 をインストールすれば自動的に入るはず。」らしい
- Rでピボットテーブル
- Rデータフレーム自由自在
- Watal M. Iwasaki » R programming » reshape2 — 柔軟なデータ変形ツール
ggplot2
- デフォルトの作図コマンドよりも効率的に作図ができ、しかも分かりやすくて美しい図を描くことができるライブラリ
- Rのグラフィック作成パッケージ“ggplot2”について
scales
- グラフ描画時に軸の数値をカンマ区切りで表記してくれるライブラリ
便利ライブラリをまとめてインストール
install.packages("plyr")
install.packages("reshape2")
install.packages("ggplot2")
install.packages("scales")
install.packages("foreach")
install.packages("rpart")
install.packages("partykit")
install.packages("randomForest")
install.packages("caret")
library(plyr)
library(reshape2)
library(ggplot2)
library(scales)
library(foreach)
library(rpart)
library(partykit)
library(randomForest)
library(caret)
基本操作
ファイルやディレクトリの操作
## 作業スペースの表示
getwd()
## 作業スペースの移動
setwd("C:\\temp\\Rsample")
## パッケージのインストールと適用
install.packages("hoge")
library(hoge)
## csv読み込み
hoge <- read.csv("foo\\bar\\hoge.txt", header=T, stringsAsFactors = F)
## データフレームをテキスト出力
write.table(
data, # データフレーム
"data.csv", # ファイル名
row.names=F, # 行番号の出力は不要
sep=",", # 区切り文字
quote=T # 囲み文字あり
)
データ表示
## 先頭5件表示
head(hoge)
## 先頭10件表示
head(hoge, 10)
データの結合
## SQLでいうJoin
hoge.fuga <- merge(hoge, fuga,
by = c(
"user_id",
"app_name"
)
)
## SQLでいうLeft Outer Join
hoge.huga.foo <- merge(
hoge.huga, # 結合対象データ(X)
dpu, # 結合対象データ(Y)
by = c("log_date", "app_name", "user_id"), # 結合対象データのカラム
all.x = T # Left Join 指定
)
## 結合した側のデータの列名は.gをつける
hoge <- merge(
imp, goal, # tmpとgoalを結合
by="transaction_id", # transaction_idで結合
all.x=T, # 外部結合
suffixes=c("",".g") # 結合下側の列名にgをつける
)
データ加工
## N/Aデータを0に変換
hoge.huga$foo[is.na(hoge.huga.foo$payment)] <- 0 # foo列のデータがN/Aの場合に0を代入
## 文字を数値に変換
hoge.fuga$foo <- as.integer(hoge.fuga$foo) # 整数へ変換
hoge.fuga$foo <- as.numeric(hoge.fuga$foo) # 実数へ変換
## 数値を文字に変換
hoge.fuga$num <- as.character(hoge.fuga$num) # 文字
## 文字結合
hoge.fuga$col3 <- paste(hoge.fuga$col1, hoge.fuga$col2, "_") # 結合対象と区切り文字を指定
## SubString(yyyy-mm-dd形式のlog_date列を元にyyyy-mm形式のlog_month列を作成)
hoge.huga$log_month <-substr(hoge.huga$log_date, 1, 7) # 1文字目から7文字目を別カラムとして定義
## 場合分けでの値の設定
### hoge.fugaのuser.type列に場合分けで値を代入(コメント部のSQLの場合の書き方を併記)
hoge.fuga$user.type <- ifelse( # case when
hoge.fuga$install_month == hoge.fuga$log_month, # hoge.fuga.install_month = hoge.huga.log_month
"install", "existing" # then "install", else "existing"
) # end
# 型変換(文字->日付)
hoge$log_date <- as.Date(
hoge$log_date
)
# 重複統一(foo をA,B,C列でユニークにする。SQLでいうGroup by)
bar <- unique (
foo[, c("A", "B", "C")]
)
# 縦横変換
# > bar
# min 1Q mid 3Q max
# -1406.870 -984.490 -12.110 432.820 1985.849
# ↓
## 横データを縦データに変換
bar <- melt(foo)
# ↓
# value
# min -1406.870
# 1Q -984.490
# mid -12.110
# 3Q 432.820
# max 1985.849
## 縦データを横データに変換
### その前に縦横変換用にデータを加工
bar$rowid <- paste0(1:length(rownames(bar)))
bar$rowid <- as.integer(bar$rowid)
bar$name <- rownames(bar)
bar$dmy <- 1
# ↓
# > bar
# value rowid name dmy
# min -1406.870 1 min 1
# 1Q -984.490 2 1Q 1
# mid -12.110 3 mid 1
# 3Q 432.820 4 3Q 1
# max 1985.849 5 max 1
### 変換
hoge <- dcast(
bar, # 対象データ
dmy ~ rowid + name, # 行データ ~ 列データ(列データは+演算子でつないて複数使用可能)
sum # 集計方法の指定(value列をどのように集計して縦横変換するか)
)
# ↓
# > hoge
# dmy 1_min 2_1Q 3_mid 4_3Q 5_max
# 1 1 -1406.87 -984.49 -12.11 432.82 1985.849
hoge <- test3[,c(-1)]
# ↓
# 1_min 2_1Q 3_mid 4_3Q 5_max
# 1 -1406.87 -984.49 -12.11 432.82 1985.849
# 行名を列に適用
test2$name <- row.names(test2)
test2$name <- rownames(test2) ## どっちでも同じ
# 行番号を列に適用
test2$rowid <- paste0(1:length(rownames(test2)))
# 連続データを階級値(区分)で分割
## 1~400の連続データを10刻みのデータに分割(階級分け)
## 他に適切なやり方ありそうだけど…
pvec <- seq(0,400,10) # データを区切るうえでのルール(0から400までを10刻み)
pvec2 <- seq(1,400,10) # 区切ったデータの階級値(1から400まで10刻み)
data$rank_div <- cut(
data$rank, # 元になる連続データ
breaks = c(pvec), # 区切り方
labels = c(pvec2), # 区切った際の階級値
right = FALSE, # m≦データ値<n
ordered_result = TRUE # ソートするか(デフォルトはFALSE)
)
グループ化
## ddplyパッケージを使用
hogeMonth.payment <- ddply(
hoge, # From 句
.(log_month, user_id, install_month), # Select 句, Group by 句
summarize, # 集計
payment = sum(payment) # Select 句 sum(payment) as payment
)
imp.summary <- ddply( # SQL で言うと...
imp, # from tmp
.(log_date, test_case), # select log_date, test_case group by log_date, test_case
summarize, # 集計
cvr=sum(is.goal)/length(user_id) # select sum(is.goal/length(user_id)) as cvr
)
## 元データに集計結果を追加
imp.summary <- ddply(
ab.test.imp.summary, # from
.(test_case), # group by
transform, # 集計ではなく元データに追加
cvr.avg=sum(cv)/sum(imp) # select sum(cv)/sum(imp) as cvr.avg
)
グラフによりデータを可視化する
## 1画面に複数グラフをまとめてプロットしたい場合
par(mfrow=c(3,3)) # 3 × 3 で9枚
## ggplotで1画面に複数グラフをまとめてプロットしたい場合
### 必要なライブラリ
library(grid)
### 出力設定(ここでは3 × 3 で9枚)
pushViewport(viewport(layout=grid.layout(3,3)))
### 出力(1,1 の箇所にggplotデータ(g.data)を出力)
print(g.data, vp=viewport(layout.pos.row=1,layout.pos.col=1))
## 基本的なグラフ
###グラフクリア
plot.new()
### グラフを重ねて描画する際のオプション
par(new=T)
### 一行折れ線グラフ
#### test
#### min 1Q mid 3Q max
#### -1406.870 -984.490 -12.110 432.820 1985.849
plot(test, type="p") # 点
plot(test, type="l") # 線
plot(test, type="b") # 点線
plot(test, type="o") # 点線(点と線が重なる)
### 散布図
x <- 1:10
y <- 1:10
plot(x, y)
### その他基本オプション
plot(
test, # データ
ylim = c(-2000, 2000), # Y軸の上限と下限
ylab = "hoge" # Y軸の名前
)
## ヒストグラム
ggplot(
hoge.fuga.summary, # 使用データ
aes(
x = log_month, # X軸
y = total.payment, # Y軸
fill = user.type # 出力対象データ
)
) + geom_bar(
stat="identity" # こう記述することで、X軸、Y軸の具体的な値をプロットできるようになる。
) + scale_y_continuous(
label = comma # Y軸をカンマ区切りで表記
)
## X軸の並び順指定
ggplot(
hoge.fuga.summary,
aes(
x=reorder(log_month, rowid),
y=total.payment,
fill=user.type
)
) + geom_bar(
stat="identity"
)
## 条件に合致するデータのみをグラフに描画
ggplot(
hoge.fuga[
hoge.fuga$payment > 0 & # payment列データが0より大きい かつ
hoge.fuga$user.type == "install", # user.type列が"install"
], # の場合、
aes(
x = payment, # X軸にPayment
fill = log_month # 出力対象データはLog_monthのカウント
)
) + geom_histogram(
position = "dodge", # 横並び
# position = "fill", # 割合
# position = "stack", # 積み上げ
# position = "identity", # 重ねて描画
# alpha = 0.5, # 透過指定
binwidth = 2000 # 棒の太さ
)
## 折れ線グラフ
limits <- c(0, max(hoge$dau)) # 下準備
ggplot(
hoge, # 対象データ
aes(
x = log_date, # X軸
y = dau, # Y軸
col = device_type, # 色の指定
lty = device_type, # 線の指定
shape = device_type # マークの指定
)
) + geom_line(
lwd = 10 # 線の太さ
) + geom_point(
size = 4 # マークの大きさ
) + scale_y_continuous(
label=comma, # Y軸は1000と1,000と表記
limits=limits # Y軸の上限、下限を指定
)
## 補助線ありグラフ
limits <- c(
0,
max(ab.test.imp.summary$cvr)
)
ggplot(
ab.test.imp.summary,
aes(
x=log_date,
y=cvr,
col=test_case,
lty=test_case,
shape=test_case
)
) + geom_line(
lwd=1
) + geom_point(
size=4
) + geom_line( # 補助線を指定
aes(
y=cvr.avg, # Y軸に平均値を表示
col=test_case # test_case毎に色を指定
)
) + scale_y_continuous(
label=percent,
limits=limits
)
#散布図と回帰直線
ggplot (
data.access_and_score,
aes (
x=score, # X軸
y=access_cnt # Y軸
)
) + geom_point ( # 散布図の描画設定
aes(colour=period), # periodで点を色分け
shape = 20,
size = 0.8,
na.rm = TRUE
) + geom_smooth ( # 近似線を追加
aes(
colour=period, # periodで色分け
group=period # periodでグルーピングして複数の線を描画
),
method = "lm" # 回帰法を利用
)
# + geom_smooth() # とすると平均値線を追加
+ theme(legend.position="none", axis.title.y=element_text(size="20")
)+ labs(title="65-1",y="P2")
# グラフの見た目設定
ggplot (
data,
aes ( x=P1, y=P2)
) + geom_point (
col = rgb(0.8,0.1,0.1),
shape = 20,
size = 2,
na.rm = TRUE
)+ theme(
legend.position = "none", # 凡例非表示
axis.title.y = element_text(size="20") # Y軸タイトルの設定
axis.text.y = element_text(size="20") # Y軸の設定
)+ labs(
title="65-1", # グラフタイトル
y="P2" # Y軸タイトル
)
クロス集計
# シンプルケース
table(
hoge.info[, c("log_month", "gender")] # X軸:log_month, Y軸:genderでデータ件数をクロス集計、プロット
)
tableData <- table(hoge.info[, c("log_month", "gender")]) # テーブルデータを変数に格納
tableDataSum <- addmargins(tableData) # 合計列、合計行を追加
tableDataSum # 合計行を含むデータをプロット
## モザイク形式でデータを表にプロット
mosaicplot(
tableData, # テーブルデータ
color=T, # 色を付けるか
shad=T # 残差を可視化するか
)
## セグメント分析(性別×年代で集計)
dcast( # reshape2パッケージの関数(縦横変換)
hoge.info, # 集計対象データ
log_month ~ gender + generation, # log_monthを軸にgenderとgenerationの組み合わせクロス集計
value.var = "user_id", # user_idを計数として使用
length # 件数を集計
)
ベクトル
ベクトル = 2個以上のデータの集まりで,スカラーを縦列に並べたもの
sales<-c(15,20,25,10,30)
sales # [1] 15 20 25 10 30
length(sales) # 5
fruits<-c("cherry", "apple", "grape", "banana", "other")
## ベクトルに名前をつける
names(sales)<-fruits
sales
### cherry apple grape banana other
### 15 20 25 10 30
χ2乗検定
## test_caseとis.goalの関係性をχ2乗検定で確認する
chisq.test(
imp$test_case,
tmp$is.goal
)
回帰分析
fit <- lm(
install ~ ., # モデルの指定(install = tvcm, magazine というモデルで重回帰分析を実施)
# install ~ tvcm + magazin と記述しても同じ意味になる
# . を使うことで、install 以外全て、の意味になる
data = ad.data[, c("install", "tvcm", "magazine")]
)
## 各種係数を表示
fit
# Coefficients:
# (Intercept) tvcm magazine
# 188.174 1.361 7.250
# --> install = 1.361 * tvcm + 7.250 * magazine + 188.174
## 回帰分析の結果を表示
summary(fit)
# 残差
# Residuals:
# Min 1Q Median 3Q Max # 最小値 | 第一四分位数 | 中央値 | 第二四分位数 | 最大値 |
# -1406.87 -984.49 -12.11 432.82 1985.84
# 重回帰モデルの係数
# Coefficients:
# Estimate Std. Error t value Pr(>|t|) # 推定値 | 標準偏差 | t値 | p値 |
# (Intercept) 188.1743 7719.1308 0.024 0.98123 # 切片(定数項)
# tvcm 1.3609 0.5174 2.630 0.03390 * # tvcm
# magazine 7.2498 1.6926 4.283 0.00364 ** # magazine
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# 自由度
# Residual standard error: 1387 on 7 degrees of freedom
# Multiple R-squared: 0.9379, Adjusted R-squared: 0.9202
# F-statistic: 52.86 on 2 and 7 DF, p-value: 5.967e-05
ロジスティック回帰分析
### glm() --> ロジスティック回帰を実施
### step() --> モデルに使う説明変数を自動で探索・選定
fit.logit <- step(
glm(
is_sp ~ ., # モデルの形式(is_spを説明するために、それ以外の項目全てを使用)
data = fp.dau1.cast[, -1], # データ((-1)でuser_idを除外)
family = binomial # 分布族(binomial :二項
# gaussian :正規
# poisson :ポアソン
# Gamma :ガンマ
# Inverse.gaussian:逆正規)
)
)
summary(fit.logit)
# Call:
# glm(formula = is_sp ~ d1 + d4 + d5 + d7 + d10 + d13 + d22 + d29 +
# d31, family = binomial, data = fp.dau1.cast[, -1])
## 残差の分布
# Deviance Residuals:
# Min 1Q Median 3Q Max
# -1.95538 -0.45175 -0.23178 -0.06122 2.69461
## 係数の推定値のサマリ
# Coefficients:
# Estimate Std. Error z value Pr(>|z|)
# (Intercept) -3.6036 0.4269 -8.441 < 2e-16 ***
# d11 1.5334 0.5720 2.681 0.00735 **
# d41 1.7753 0.6424 2.764 0.00572 **
# d51 -1.0353 0.7622 -1.358 0.17437
# d71 1.7002 0.7109 2.392 0.01678 *
# d101 -2.6753 0.9418 -2.841 0.00450 **
# d131 1.3726 0.7547 1.819 0.06893 .
# d221 1.6233 0.6382 2.543 0.01098 *
# d291 2.0012 0.6480 3.088 0.00201 **
# d311 1.7310 0.8143 2.126 0.03352 *
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# (Dispersion parameter for binomial family taken to be 1)
# Null deviance: 281.20 on 251 degrees of freedom
# Residual deviance: 126.73 on 242 degrees of freedom
## 赤池情報量規準
# AIC: 146.73
# Number of Fisher Scoring iterations: 6
# 作成されたモデルを利用した予測
fp.dau1.cast$prob <- round(
fitted(fit.logit),
2
)
# 予測
fp.dau1.cast$pred <- ifelse(fp.dau1.cast$prob > 0.5, 1, 0)
# 予測と実測
table(fp.dau1.cast[, c("is_sp", "pred")])
基本統計量 算出関数
基本統計量 | 関数 |
---|---|
合計 | sum |
算術平均 | mean |
最大値 | max |
最小値 | min |
範囲 | range |
中央値 | median |
分散 | var |
標準偏差 | sd |
分位数 | quantile |
統計要約 | summary |