ルビスコくん空を飛ぶ

博士学生(D1)の日記です.日記に加えてプログラミング(R)のメモ書きもします.

学振DC1の面接候補になりました

この5月に申請書を学振に提出していたのですが,その審査結果が返ってきました.提出した時点で申請書の出来は悪いと思っていたのですが,結果は「面接候補」でした.学振の採用の仕方として,採用(面接免除)・不採用・その間のグレーゾーン「面接候補」があります.よく言えば「一次審査に通った」,悪く言えば「書類だけでは通らなかった」ということになります.私が出した領域の申請者は450人だったので,面接に呼ばれたということは上位25%に入ったということになります.他のブログとかTwitterを見ていると「面接かよ…」と肩を落としている人がちらほらいますが,私は面接候補と知ってけっこううれしく思っています.そんな質の高い申請書を書いたつもりは全くなかったので.

5ヶ月前に提出した申請書をもう一度読んでみると,最初のページ(「現在までの研究状況」)の内容は結構わかりやすく書いてあるなという印象を持ちました.一方でこれからの研究計画については目的もはっきりしないし,背景知識を多くもたない審査員にとってはわかりにくい説明になってしまったのではないかと思います.業績は論文0報(準備中が1つ),海外学会1件,国内学会多数,民間助成金1件だったので,少なくはないが論文がないのがネック,という状態でした.業績はあまりプラスにはならなかったと思います.それでも面接に残ったのは,やはり審査員の第一印象が原因だと思います.つまり最初のつかみのところでわかりやすくこれまでの自分の研究をアピールできれば,少々計画がまずくても面接に呼ばれる程度の点数はもらえるということかもしれません.

書類だけで一発採用にはならなかったのですが,なんとか首の皮一枚つながった感じです.私が申請した領域では毎年90人ほど採用されており,今年の面接免除は72人,面接候補は33人だったので,今年も90人採用されると仮定すれば,面接まで残れば大体半分強は採用される計算になります.ここまでくれば頑張るしかありません.

面接は12月の頭に行われ,持ち時間は10分(4分発表+6分質疑応答).計画についてまだつめられていないところが結構あるので,がんばります.

回帰直線を引いて同時に回帰式も図に表示させる

わかりやすくするために図の中に式を埋め込みたいけど,式をRで調べていちいちパワポイラストレータなどで文字を打ち込むのは時間の無駄なのでRで(ggplotで)やってしまいましょう.今回もデータセットはairqualityを使います.

f:id:pam715:20161011163649p:plain

この中のOzoneとTempの回帰式の傾き,切片,r2値を調べる.

res <- summary(lm(airquality$Ozone ~ airquality$Temp))
slope <- round(res$coef[2], digits = 3)
intc <- round(res$coef[1], digits = 3)
rsq <- round(res$r.squared, digits = 3)

傾きはslope,y切片はintc,r2値はrsqに格納できた.後で図中に落として見にくくならないようにround()で有効数字を決めておく.

次にggplot2で散布図を描いてannotateで式を書く.

ggp <- ggplot(airquality, aes(x = Temp, y = Ozone))
gm <- geom_point()

lyr <- ggp + gm + geom_smooth(method = "lm", se=F) + theme_bw() +
annotate("text", label = paste0("y==", slope, "*x + ", intc), x = 70, y = 150, parse = TRUE, size = 10) +
annotate("text", label = paste0("r2==", rsq), x = 70, y = 130, parse = TRUE, size = 10)

 annotate()では,"x ="と"y ="で文字の位置を決める.

f:id:pam715:20161011165516p:plain

y切片の表示が"+-"になっているし"r2"が上付け文字になっていないが… 

 

Rで素数判定プログラム

気になる自然数を入力するとその数が素数かどうかを判別してくれるプログラムを,思いつきでつくってみました.その理屈はいたって簡単.自然数Xを2から順番に割っていって,初めて割り切れた数がXなら素数ですから"X is a prime number!",それ以外なら"X is NOT a prime number!"と表示させます.

readline("Natural number? ")でこの関数を実行したときに"Natural number? "と聞いてくるようにしています.入力された数字は文字列なのでas.numeric()で数値に変換.

prime_n <- function(){
x <- as.numeric(readline("Natural number? "))
is_integer <- function(values){
all(values %% 1 == 0)
}
for(i in (2:x)){
if(is_integer(x / i) == T) break
}
if(i == x) cat(paste0(x, " is a prime number!"))
else cat(paste0(x, " is NOT a prime number!"))
}

実際に実行してみると...

f:id:pam715:20160921131747p:plain

と聞いてくるので数値を入力.

f:id:pam715:20160921131900p:plain

f:id:pam715:20160921132002p:plain

来年は素数の年なんですね.ちなみに見てもわかるとおり,このやり方はXを2からforループを回して順番に割っていくというかなり効率の悪い計算法ですので,例えば2000000009のような大きな数字を入力してしまうとかなり時間がかかります.

read.csv()の段階で列名を指定する

col.names = で指定できる.
read.csv(x, header = F, skip = 1, col.names = c("T-Yamada", "T-Okada", "T-Kanemoto"))

2種類のカテゴリデータにそれぞれ色とプロットのマーカーを割り当てて散布図を描きたい

「変数XとYの関係に,別の変数ZとWが与えている影響をみたいとき」はXとYをプロットしZとWで色とマーカーを変えた図を出すという方法がある(ただし図が煩雑にはなるのは想像に難くない).こんな図は,描画パッケージggplot2を使えば簡単にできる.

例に使うデータセットはairqualityとする.XにSolar.Rつまり太陽放射,YにOzone(オゾン濃度)をプロットし,気温Tempと風速Windを,それぞれ3つのクラスにわけて,それぞれ色とマーカーでわける.

まずはTempとWindを3つのクラスに分ける.

rad <- cut(airquality$Solar.R, breaks=c(0, 100, 200, 500), labels=c("~100", "100~200", "200~"))
win <- cut(airquality$Wind, breaks=c(0, 8, 12, 50), labels=c("~8", "8~12", "12~"))

 

f:id:pam715:20160730140820p:plain

cut()は連続的な変数をカテゴリに変換する関数で,"labels="以降にそれぞれのカテゴリに対する名前を振り分けることができる.あとはプロットするだけ.

library(ggplot2)
pl <- ggplot(airquality, aes(x=Temp, y=Ozone))
pl2 <- pl + geom_point(aes(colour=factor(rad), shape=factor(win)), size=8) + theme_bw()
print(pl2)

f:id:pam715:20160730141657p:plain

すごく便利.

ただ,これをもしR標準のplot()でやろうとすると,少し工夫が必要である.まず,カテゴリの名前を1, 2, 3という数字にして変数を分類して,pchとcolに行列として入れてしまえばよいと私は思った.つまり,

rad <- cut(airquality$Solar.R, breaks=c(0, 100, 200, 500), labels=1:3)
win <- cut(airquality$Wind, breaks=c(0, 8, 12, 50), labels=1:3)
plot(airquality$Temp, airquality$Ozone, col=rad, pch=win)

こういうことだ.radで色,winでマーカーを指定できていると思いきや,これではエラーがでた.

f:id:pam715:20160730142544p:plain

ちなみにcolだけなら大丈夫.pchがこのような指定の方法ができないらしい.

f:id:pam715:20160730142820p:plain

 

パッケージggplot2による2軸表示

先日,Rのパッケージggplot2のグラフ2軸機能 - ルビスコくん空を飛ぶでggplot2ではグラフの2軸は表示できないという記事を書いたが,どうやらできるようになったらしい.「plotflow」パッケージをインストールするために,以下のようなコマンドを打ち込む.

f:id:pam715:20160626112506p:plain

では,以下に例を示す.今回用いるデータは,Rに標準装備されているデータセットairqualityで,横軸に5月1日から数えた日数,左の軸に大気中オゾン濃度,右の軸に気温(華氏)をおいて,二種類のデータをプロットすることを目的とする.

まずはairqualityの概観から.Ozone

f:id:pam715:20160626121434p:plain

library(plotflow) #パッケージを読み込む

fonts <- theme(axis.text.x = element_text(size=15),axis.text.y = element_text(size=15),
legend.position=c(0.9, 0.9), legend.text=element_text(size=20)) + theme_bw() #ggplotの設定いろいろ

airquality$Day2 <- 1:length(airquality$Day) #5月1日からの日数をつくる

TwoGGPlot <- ggplot(airquality, aes(x = Day2, y = Ozone))
Ozoneplot <- TwoGGPlot + geom_line() + ylim(0, 200) + fonts

TwoGGPlot2 <- ggplot(airquality, aes(x = Day2, y = Temp))
Tempplot <- TwoGGPlot2 + geom_line(aes(colour="red")) + ylim(0, 100) + fonts

ggdual_axis(lhs = Ozoneplot, rhs = Tempplot) #最後にggdual_axis()を入力.lhsは左軸,rhsに右軸にしたいグラフを入力すると次のようなグラフが表示される.

f:id:pam715:20160626122545p:plain

ちなみに,本題とは関係ないですが気温と大気中オゾンには正の相関が見られます.

ggplot(airquality, aes(x = Temp, y = Ozone)) + geom_point() + fonts + stat_smooth(method = "lm", se=F)

f:id:pam715:20160626123026p:plain

文字列から特定の文字列を削除する

"hogehoge.txt"という文字列から".txt"を削除する方法.list.files()などでファイル名を取り出したのはいいが,拡張子は削除したい,というときに便利.

gsub()を使う.

f:id:pam715:20160624211757p:plain

一つ目の引数に検索文字列,次の引数に置換後の文字列,最後に置換したい文字列を入力する."hogehoge.txt"で,".txt"を""(空白)に置換すると"hogehoge"になるし,"oge"を""(空白)に置換すると"oge"がすべて削除されて"hh.txt"という文字列が返される.最初の"oge"だけを置換したい場合は,sub()を用いる.

f:id:pam715:20160624212218p:plain

私はひとつのテキストファイルからグラフを書いて,jpgファイルに元のテキストファイルのファイル名を反映させるために用いた.これができれば以下のような関数ができる.応用というほどでもないが.

1. ファイル名入力

2. ファイルをread.table()などで読み込む

3. 読み込んだファイルからグラフを描き,jpg()で保存する.jpg()の引数(保存するファイルのパス)としてファイル名を入力する.その際1で得たファイル名から拡張子を削除した文字列に".jpg"をpaste()で追加する.

以上のような関数(hogeと名づけるとする)を使うと,「ファイル名の取得 => グラフごとにファイル名を変更しながらグラフの描画」を自動化できる.例えば,

lf <- list.files(pattern=".txt") #ディレクトリないのテキストファイルを束ねる

mapply(hoge, lf) #hogeという関数をlfの要素に順々に適用していく

これでグラフの描画も楽チンになるはず.