大学の卒業論文執筆の際にR言語を使用して分析を行っていたものの、卒業してから10年以上使うことがなく記憶の彼方に飛んでいたR言語ですが、PCのデータ整理をしていたところ当時のRのコードと論文が出てきたので、これを機に振り返りながら思い出してみようと思います。
「プログラミング言語大全」(著:クジラ飛行机)では、R言語はデータ分析においてはPythonと並んで重宝され、そこそこ将来性がある言語ではあるものの、PowerShellやTypeScriptと同じくらいの難易度とのことで、一から読むのは結構厳しい気がしますのでAI(ChatGPT5.2)に解読してもらったりして振り返っていこうと思います。
この記事は、
- 昔Rを触っていた人
- 卒論・研究でRを使っていた人
- これからRを触ってみたい人
に向けた、振り返り記録です。
※分析手法の統計学的な内容に興味がある方は書籍などで確認してください。
当時の環境
まずは当時の開発環境から。
- 使用時期:2012年頃
- OS:Windows 7(研究室) / Windows Vista(私用PC)
- Rのバージョン:不明
- エディタ:RStudio(だったはず)
卒論で何を分析していたか
ざっくりですが、卒論では以下のような分析を行っていました。
- テーマ:施設立地統計に関する分析
- データ内容:
- サンプル数:数万件(公的調査)
- 変数:事業所開設年(西暦)、延床面積、従業者数、所在地、業種など
- 分析手法:
- 条件ごとに無作為抽出
- 東京駅からの距離ごとに分析
- 空間的自己相関分析
- 密度曲線(カーネル密度推定)
- 風船プロットなど
当時のRコードを見てみる
実際に残っていたコードの一部がこちら。
データの読み込み
d <- read.csv("C:/users/<ユーザー名>/documents/<ファイル名>.csv")
dt <- d[d[ ,n] > 0,]
#documentsフォルダに保存されたCSVファイルを読み込んで、Rのデータフレームとして d に入れる
#データフレーム d から、n列目の値が正(>0)の行だけを取り出して dt に保存※ノイズを除くため
無作為抽出
対象全体の中から、どれが選ばれるかを完全にランダムに決めて抽出する方法
a2 <- sample(a1, size=100, replace = TRUE)
#AIに読んでもらったところ👆のコードは❌「行を無作為抽出」にはなっておらず、
#Rの仕様上、👉 データフレーム a2 をベクトル扱いして、中身の要素(列や値)をサンプルしてしまうらしく、
#正しく「行を無作為抽出」するなら👇
a2 <- a1[sample(nrow(a1), 100, replace = TRUE), ]
#と書くみたいです。
東京駅(固定点)から、CSVに載っている各地点までの直線距離(地球表面上)を計算
緯度経度を用いて地点間の距離を求めます
keido01 <- 139.7672
ido01 <- 35.68112
#東京駅の緯度経度
p <- pi/180
ido02 <- cbind(dt[ ,<緯度が記載された列>])
keido02 <- cbind(dt[ ,<軽度が記載された列>])
d1 <- sin(ido01*p)*sin(ido02*p) + cos(ido01*p)*cos(ido02*p)*cos(keido01*p - keido02*p)
d2 <- acos(d1)
d3 <- d2*6370
#球面余弦定理を使用
空間的自己相関分析
「近くにあるもの同士が、似た値を持っているか?」を定量的に調べる分析です。
1)空間重み行列 W を作っている部分(隣接=4近傍)
w <- matrix(0,nrow=ns,ncol=ns)
for (n in 1:ns){
ix <- dt[n,3]; iy <- dt[n,4]
w[ mesh[ix,iy,2] , mesh[ix-1,iy,2] ] <- 1
w[ mesh[ix,iy,2] , mesh[ix+1,iy,2] ] <- 1
w[ mesh[ix,iy,2] , mesh[ix,iy-1,2] ] <- 1
w[ mesh[ix,iy,2] , mesh[ix,iy+1,2] ] <- 1
}
for (n in 1:ns){
aa <- sum(w[n,])
if(aa!=0) w[n,] <- w[n,]/sum(w[n,])
}
#「格子状にIDを振っていmesh[x,y,2] がセルID
2)Moran’s I を計算している部分(グローバル Moran’s I)
wsum <- sum(w)
moran <- sum( w * ( (z-ave) %*% t(z-ave) ) )
moran <- moran/(wsum*(vari))
cat("Moran'I: ",moran,"\n")
密度曲線(カーネル密度推定)
density(dt[,n])
#dt のn列目の数値データについて、「どれくらい集中しているか」の分布の形を「なめらかな確率密度関数」として推定する
密度曲線はヒストグラムをなめらかにした連続的な推定で、ヒストグラムと違って異なる条件で絞った曲線同士の比較がしやすいという特徴があります。
風船プロット
データの大きさ(量)を「風船の大きさ(円の面積)」で表すグラフ
library(gregmisc)
balloonplot( inout[,1],inout[,2],inout[,3], ylab ="搬入元", xlab="搬出先",main="業種ごと")
#業種ごとに搬入元 × 搬出先 × 規模 をバブルの大きさで表した関係図を描く
卒論に記載してあった参考文献
R言語の学習に本当にこれがおすすめというよりは、大学の図書室や自治体の図書館で借りることができた本です。
地理空間データ分析 (Rで学ぶデータサイエンス 7) 単行本 – 2010/7/25 谷村 晋 (著), 金 明哲 (編集)
ネットワーク分析 第1版 (Rで学ぶデータサイエンス 8) 単行本 – 発売日不明 金 明哲 (編集), 鈴木 努 (著)
今であれば下記の本の方が汎用性が高くてお勧めかと思います。
Rクックブック 第2版 単行本(ソフトカバー) – 2020/1/17
J.D.Long (著), Paul Teetor (著), 大橋真也 (著)
また、下記は今話題のAIの機械学習の書籍のようです。R言語でAIを扱っている書籍はこの時代からあったのですね。
マシンラーニング 第2版 (Rで学ぶデータサイエンス 6) 単行本 – 2015/2/24 辻谷 將明 (著), 竹澤 邦夫 (著), 金 明哲 (編集)
※AIに聞いたところ、空間的自己相関を用いたAIのモデル系統はガウス過程(明示的・理論的)、空間回帰(明示的)、GNN(構造として明示)、CNN(暗黙的)、Transformer(学習的・暗黙的)とのことです。
今の自分から見た感想
10年以上ぶりにRのコードを見返して、改めて感じたことがあります。
• R言語が「難しい」と言われがちなのは、文法そのものよりも「統計学をある程度理解していることが前提」の言語だからではないか?
• 関数名や書き方以前に、「この結果をどう解釈するのか」が分からないと先に進めない
• AIに聞いてみて実は間違っているコードがあったと知ってショック
• コードを読めば、どのような手順で分析を行ったのかが分かるため、UI操作による集計と比べて再現性が高い
• 高校レベルの数学をやり直したい
学生時代は「とにかく動かす」ことで精一杯でしたが、
今振り返ると Rは「統計を実装するための言語」だったのだと実感します。
今後このシリーズでやりたいこと
このシリーズでは、単に懐かしむだけでなく、
「今ならどうやるか?」 をテーマに以下も試していきたいと思います。
• 当時のコードを最新のR環境で動かしてみる(動かないかも…)
• 同じ分析をPower BIのRスクリプトビジュアルで再現できるか
• Python(pandas / statsmodels / scikit-learnなど)で同様の分析が可能か検証
• R・Python・Power BIそれぞれの書きやすさ、可視化のしやすさ、結果の解釈のしやすさ、学習コストを比較してみる
等やってみたいです。