StatsBeginner: 初学者の統計学習ノート

統計学およびR、Pythonでのプログラミングの勉強の過程をメモっていくノート。たまにMacの話題。

Rで忘れがちな書き方(随時追記)

よく忘れることのメモです。

  • NAかどうかの判定にはx==NAとかではなくではなくis.na(x)を使う
  • 要素に含まれるかどうかの判定は、%in%かis.element()を使う。これはデータ全体の中から何かを抽出するときの条件を複数条件にしたい場面でも使えるときがある。(たとえば簡単なところでは、subset()でデータフレームから条件付の抽出をするとき、&で条件を並べなくてもよくなったりとか)
> is.element(3, c(1,2,3))
[1] TRUE
> 3 %in% c(1,2,3)
[1] TRUE
  • {dplyr}でデータフレームを操作した後、as.data.frame()で標準のデータフレームに戻してからじゃないと、別の関数に与えたときにエラーが出る場合がある
  • {data.table}のfread()関数でcsvとかを読み込んだ場合も、それを標準のデータフレームにしてから使わないとエラーが出ることがある
  • factor型のデータをnumericに変えると、factorの中身ではなくレベル(水準)番号が数字になる。
> x <- as.factor(c(1,10,100,1,10,100))
> as.numeric(x)
[1] 1 2 3 1 2 3
  • リストに要素をアペンドするとき、c()関数でできるのだが、付け加える方にlist()をかけとかないといけない
> x1 <- c(1,2,3)
> x2 <- c('a','b','c')
> l1 <- list(x1, x2)
> print(X)
[[1]]
[1] 1 2 3

[[2]]
[1] "a" "b" "c"

[[3]]
[1] "あ"

[[4]]
[1] "い"

[[5]]
[1] "う"

> x3 <- c('あ','い','う')
> l2 <- c(l1, x3)  # これはダメ
> print(l2)
[[1]]
[1] 1 2 3

[[2]]
[1] "a" "b" "c"

[[3]]
[1] "あ"

[[4]]
[1] "い"

[[5]]
[1] "う"

> l3 <- c(l1, list(x3))  # こうする
> print(l3)
[[1]]
[1] 1 2 3

[[2]]
[1] "a" "b" "c"

[[3]]
[1] "あ" "い" "う"
  • データをロング型にしたりワイド型にしたりするのには{tidyr}を使う。ワイドをロングにするのはgather()関数で、ロングをワイドにするのはspread()関数で。
  • ||とか&&は、or/and条件を入れ子にするときに使う。
  • ベクトルの要素が「全て◯◯という値である」という条件を書くシンプルな方法はたぶんない?最大と最小が一致するみたいな書き方をいつもしているのだが。
  • データを「中心化」(平均ゼロにする)したいときは、center()じゃなくて、scale()関数のオプションでscale=Fに設定する。変な話だが。

[メモ]Mac版のRでパッケージのインストールに失敗(X Codeのアプデが必要だった)

さっきハマったエラーを解決したので、備忘のためのメモです。
RStudioとRの両方で試したのですが、{panelvar}というパッケージをインストールしようとしたら、依存パッケージのコンパイルのエラーがでて進めなくなりました。
最初、Rの古いバージョンでやってたら{progress}というパッケージで躓いたんですが、Rを最新版にアプデしてからやると今度は{vctrs}というパッケージがインストールできてませんでした。
{vctrs}だけをインストールしようとしてもエラーが出る。

ERROR: compilation failed for package ‘vctrs’
* removing ‘/Library/Frameworks/R.framework/Versions/3.6/Resources/library/vctrs’
Warning in install.packages :
  installation of package ‘vctrs’ had non-zero exit status

The downloaded source packages are in
	‘/private/var/folders/7y/j9v534hs3hb971070xnz91l80000gp/T/Rtmp9EalBG/downloaded_packages’
Error: package or namespace load failed for ‘panelvar’:
 .onLoad failed in loadNamespace() for 'pillar', details:
  call: utils::packageVersion("vctrs")
  error: there is no package called ‘vctrs’
* installing *source* package ‘vctrs’ ...
** package ‘vctrs’ successfully unpacked and MD5 sums checked
** using staged installation
** libs
clang -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -I/usr/local/include  -fPIC  -Wall -g -O2  -c arg-counter.c -o arg-counter.o
clang: warning: no such sysroot directory: '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk' [-Wmissing-sysroot]
In file included from arg-counter.c:1:
In file included from ./vctrs.h:2:
/Library/Frameworks/R.framework/Resources/include/R.h:55:11: fatal error: 'stdlib.h' file not found
# include <stdlib.h> /* Not used by R itself, but widely assumed in packages */
          ^~~~~~~~~~
1 error generated.
make: *** [arg-counter.o] Error 1
ERROR: compilation failed for package ‘vctrs’
* removing ‘/Library/Frameworks/R.framework/Versions/3.6/Resources/library/vctrs’
Warning in install.packages :
  installation of package ‘vctrs’ had non-zero exit status

The downloaded source packages are in
	‘/private/var/folders/7y/j9v534hs3hb971070xnz91l80000gp/T/Rtmp9EalBG/downloaded_packages’


これは、こないだのMac OSのアプデ時に、X Code最新化(コマンドラインツールのインストール)しておくべきだったのが原因のようです。
下記のサイトで2段階の解決方法が紹介されてますが、私は1段階目の"xcode-select"で治りました。
_cgo_export.c:3:10: fatal error: &#39;stdlib.h&#39; file not found の解決方法 - Qiita

Macで画像ファイルをまとめてPDF化する(ただし名前順にソート)

Macで画像ファイルをまとめてPDFにしたいとき、従来はAutomatorを使ってワークフローを組んでいました。
ところが、いつからか知らないですが、OSに標準でそういう機能が付けられていたようです。
ついさっき、ある人から、とある論文のPDF入手を頼まれたのですが、諸事情により画像ファイルでしか閲覧できないので、これをPDF化しようとしていて気づきました。


f:id:midnightseminar:20191119120648p:plain


上のように、ファインダーで複数の画像を選択すると、右下のところに(これはサービスというやつですが)「PDFを作成」というボタンがあって、これを押すと選択した画像をまとめたPDFがそのフォルダに作成されます。


これは神!と思ったのですが、どうも、ファインダーで選択した順番にPDFに入っていくようです。
個人的には、どちらかといえば「選択したやつ全部を名前の順にソートしてPDF化」あるいは「フォルダ内の画像を名前順にまとめてPDF化」したい場合が多いので、やっぱりAutomatorで組んでおくことにしました。
作業としては2分ぐらいで終わります。


まずAutomatorを開いて新規作成で「クイックアクション」を選択。これはOS内で「サービス」と呼ばれる機能を提供するものです。


f:id:midnightseminar:20191119121220p:plain


次に、ワークフローの画面の一番上にあるところは(右の上)では、「ワークフローが受け取る現在の項目」は「ファイルまたはフォルダ」にしておき、「検索対象」は「Finder.app」を選んでおきます。
その上で、左の処理一覧から、処理したい項目を次のように選びます(右のワークフロー欄にドラッグする)。

  1. 「ファイルとフォルダ」から「選択されたFinder項目を取得」を選択
  2. 「ファイルとフォルダ」から「Finder項目にフィルタを適用」を選択し、「種類」が「イメージ」であるという条件を設定
  3. 「ファイルとフォルダ」から「Finder項目を並べ替える」を選択し、「名前」の「昇順」でソートするようにしておく
  4. 「PDF」から「イメージから新規PDFを作成」」を選択し、保存先は適当に決めておいて、出力するときの名前も決める。サイズは「ページをサイズに合わせる」にしておけば、勝手に画像が圧縮されたりしなくていいと思います。


f:id:midnightseminar:20191119121922p:plain


これだけやって保存しておけば、ファインダーで画像を選択したときに、さきほどの「PDFを作成」の隣にある「その他」の中にメニューが出てきますし、あるいは画像を選択した状態で右クリックして「サービス」から選択することもできます。


f:id:midnightseminar:20191119122405p:plain
f:id:midnightseminar:20191119122423p:plain


なお、サービスに追加したワークフローは、"~/Library/Services"という場所に入っていて、名前を変えたいときはここでファイル名を変えればいいようです。
また、フォルダを選択してフォルダ内の画像をまとめたい場合は、ワークフローのパーツとして「フォルダの内容を取得」ってのを使えばいいです。

言語学への関心は衰退している?

とある雑誌の連載記事に、

言葉というものは曖昧かつ不安定で捉えにくい対象であることもあって、とりわけ現代思想ブームが終焉し実証的社会科学が隆盛を極めているここ三十年ほどの間は、言語理論への関心は総じて低調であったと言える。「言語論的転回」は今や、むしろ逆転の渦中にあるとみたほうがよいのかも知れない。


というようなことをあまりよく考えずにさらっと書いてしまったのですが、本当に低調であると言えるのかどうか不安になったので、Google Ngram Viewer(特定のキーワードが19世紀以降の英語の書籍にどれぐらい頻繁に登場してるかを教えてくれるやつ)で確認してみました。


【言語学】
f:id:midnightseminar:20191006190050p:plain


30年というよりは40年ぐらいかけて下落していっていますが、日本における現代思想ブームは欧米から10年ぐらい遅れていたイメージがあるので、大きく間違ってはいなかったと安心することにしました。
構造主義〜ポスト構造主義(ポストモダニズム)の時代は、人文学全般が非常に盛んで、あの時代が終わると「哲学」や「思想」とかいうもの全般に対する関心が薄れていきましたよね。まぁ私は80年代生まれなのでリアルタイムでは知りませんが。
関連しそうな用語も調べてみました。(なお、言語学や心理学の盛衰に関しては、現代思想ブームと並行して起こった、50-70年代のいわゆる「認知革命」というムーブメントも関係してると思います。)


【意味論】
f:id:midnightseminar:20191006190841p:plain


【記号論】
f:id:midnightseminar:20191006190856p:plain


【哲学】
f:id:midnightseminar:20191006190911p:plain


哲学(philosophy)はとくに人文学の議論でなくても用いられる用語なので、あまり現代思想ブームとは関係なかったかもしれません。


【人文学】
f:id:midnightseminar:20191006191153p:plain


「人文学」は90年代ごろから下落が始まるようです。


【構造主義】
f:id:midnightseminar:20191006191253p:plain


「構造主義」も意外とピークは90年代だったようです。


【人類学】
f:id:midnightseminar:20191006191237p:plain


【心理学】
f:id:midnightseminar:20191006191342p:plain


「心理学」は、ずいぶん昔にも山がありますが、これは行動主義の趨勢に引っ張られてるんですかね?
30年代ごろはパブロフとワトソン、50年ごろはスキナーの時代という感じですね。
「行動主義」も検索してみました。


【行動主義】
f:id:midnightseminar:20191006191915p:plain


【社会学】
f:id:midnightseminar:20191006191937p:plain


社会学は、ルーマンやパーソンズのような大物理論化がいた時代にピークがありますね。


人文学とは言わないと思いますが(19世紀には人文学と社会科学の区別がなかったので両者は似たようなものだったわけですが)、政治学と経済学も見てみました。


【経済学】
f:id:midnightseminar:20191006192201p:plain


【政治学】
f:id:midnightseminar:20191006192319p:plain


なんとなく、文系全体が衰退してるような感じがしますねw


しかし途中で気づいたのですが、「数学」とか「物理学」とか「統計学」とかを入力しても90年代から2000年代にかけて衰退しているので、アカデミックなワード自体が割合としては減っていくような、サンプルの性質が何かあるのかもですね。(もちろん、たとえばstatisticsなんかはとくに、アカデミックな話で使われるとも限りませんが。)


【数学】
f:id:midnightseminar:20191006192953p:plain


【物理学】
f:id:midnightseminar:20191006193010p:plain


【統計学】
f:id:midnightseminar:20191006193124p:plain

メモ:Rのts型のインデックス(年・四半期・月情報)を文字列として取り出す

Rのts型(時系列型)のデータについているインデックス("1980 Q1"みたいな)を、文字列情報として取り出す方法が、ぱっとググって分からなかったのですが、とりあえず以下のようにしたらできました。

> library(vars)
> data(Canada)
> 
> t <- as.yearqtr(index(Canada))
> head(t)
[1] "1980 Q1" "1980 Q2" "1980 Q3"
[4] "1980 Q4" "1981 Q1" "1981 Q2"
> class(t)
[1] "yearqtr"
> 
> t <- as.character(t)
> head(t)
[1] "1980 Q1" "1980 Q2" "1980 Q3"
[4] "1980 Q4" "1981 Q1" "1981 Q2"
> class(t)
[1] "character"


たぶん、元データが四半期ではなく月単位のデータだったら、yearqtrの部分をyearmonにするのだと思います。

なぜ「p < .05」で「統計的に有意」なのか?――5%基準の由来について

 以前も書いたんですが、p値が0.05を下回るかどうかにとらわれる慣習を問題視する人が最近は増えてきていて、たしかにその理由はよく理解できる一方で、p値が過剰にバッシングされている気もします。しかしそんなことより、個人的には、なぜ統計的有意性の判定基準が多くの分野で慣例的に0.05(5%)になっているのかという、その由来のほうが気になります。


 帰無仮説が正しいときにそれを棄却してしまう(第一種の過誤と呼ばれる)危険率が5%未満であれば「統計的に有意」と言われるわけですけど、この5%という閾値に客観的な必然性がないことは誰でも分かりますね。しかし実際には様々な分野で、5%基準で検定結果を報告(あわせて1%基準や10%基準での有意性も報告されたりはする)している研究が多数存在するわけです。


 この5%という基準の由来について、フィッシャーが「20年に1回ぐらいは間違っても研究者として許されるだろ」と発言したのが始まりであるという説をよく聞きます。フィッシャーは植物学者なので実験を1年に1回というペースでしか行うことができず、「20回に1回(20年に1回)ぐらいは間違った結論を出しても許してほしいよな!」と言ったという話です。
 ただ、これは単なる都市伝説だったようです。


 「5%基準」の由来を調べた論文を以前読んだのですが、
 On the Origins of the .05 Level of Statistical Significance


 アブストラクトを適当に訳しておくと、

フィッシャーの『Statistical Methods for Research Workers』よりも昔の、統計や確率に関する文献を調査すると、確かに統計的有意性に関する"5%"基準を正式に唱えたのはフィッシャーが最初であることは確かなのだが、この考え方自体はもっと昔に遡ることが分かる。偶然性の仮説を棄却するための習慣的な基準は、世紀の変わり目ぐらいから徐々に形成されていった。統計的有意性に関する初期の言及は、「確率誤差」の観点から行われている。これら初期の習慣が、フィッシャーによって採用され言及されたのである。


 この論文によると、昔は統計的有意性の判断基準として「確率誤差(ここに解説があった。)3つ分」という基準がよく使われていたらしく、これは正規分布なら「標準偏差2つ分」ぐらいに相当し、だいたい95%ぐらいになる。これが「5%基準」の由来のようです。
 つまり、確率誤差3つ分(とか標準偏差2つ分)であれば計算しやすいというか、扱いやすいので、そのへんを基準にしてものを考える習慣が5%基準に転じたのであるということのようです。

Macでひらがな・カタカナの濁点・半濁点が分離してしまったのを元に戻すスクリプト

昨日のエントリで、テキストエディタの「CotEditor」のスクリプト機能の使い方を書きました。その機能をつかって、濁点・半濁点が分離してしまったテキストを元に戻すツールを作ります。


こういうやつをなんとかしたいわけです。
f:id:midnightseminar:20190816235923p:plain



原因がよくわからないし、悩まされているのは私だけなのかも知れないのですが、Macを使っていると、PDF上から文字をコピペしたときに、濁音・半濁音のひらがな・カタカナが、1文字ではなく清音+濁点or半濁点という2文字に分離してしまう現象があります。


たとえば、Wordで以下のように入力します。ここの「ぶ」は普通の「ぶ」1文字です。
f:id:midnightseminar:20190817000024p:plain


これを、PDFで保存して、PDF上の文字列をコピーします。
f:id:midnightseminar:20190817000103p:plain


そして、たとえばエクセルに貼り付けます。比較のために、Wordからコピーした分も貼り付けてあります。
f:id:midnightseminar:20190817000119p:plain


このように、「ぶ」が「ふ」と「゛」に分かれてしまいました。
これは困るので、テキストファイル上にペーストした上で、CotEditorのスクリプトで置換できるようにしておきます。


具体的には、スクリプトは以下のように書きました。
なんかもっと美しい書き方があるような気がしてならないのですが、私にはわからないので、濁音・半濁音を全部並べることにしました。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# %%%{CotEditorXInput=AllText}%%%
# %%%{CotEditorXOutput=ReplaceAllText}%%%

import sys
import re

kana_before = ["が","ぎ","ぐ","げ","ご","ざ","じ","ず","ぜ","ぞ","だ","ぢ","づ","で","ど","ば","び","ぶ","べ","ぼ","ぱ","ぴ","ぷ","ぺ","ぽ","ガ","ギ","グ","ゲ","ゴ","ザ","ジ","ズ","ゼ","ゾ","ダ","ヂ","ヅ","デ","ド","バ","ビ","ブ","ベ","ボ","パ","ピ","プ","ペ","ポ"]

kana_after = ["が","ぎ","ぐ","げ","ご","ざ","じ","ず","ぜ","ぞ","だ","ぢ","づ","で","ど","ば","び","ぶ","べ","ぼ","ぱ","ぴ","ぷ","ぺ","ぽ","ガ","ギ","グ","ゲ","ゴ","ザ","ジ","ズ","ゼ","ゾ","ダ","ヂ","ヅ","デ","ド","バ","ビ","ブ","ベ","ボ","パ","ピ","プ","ペ","ポ"]

# 標準入力でテキストをまるごと受け取る
all_text = sys.stdin.read()

# 1個1個置き換えていく
for i in range(len(kana_before)):
	all_text = re.sub(kana_before[i], kana_after[i], all_text)

sys.stdout.write(all_text)


スクリプトの冒頭ですが、1行目はPythonインタープリタの置き場。
2行目は文字コードの宣言で、これを書いてないとエラーが出ました。(私はテキストファイルは基本的にUTF-8でしか使わないので、utf-8と書いておいた。)
3行目は、テキストファイル内の文字を全部取るという意味です。これが標準入力経由でPythonに渡ります。
4行目は、テキストファイル内の文字を全部置換するという意味です。標準出力経由でPythonからCotEditorに渡される文字列に置き換わります。


今回はとくにショートカットは指定しないことにしました。つまりスクリプトは、単に「dakuten.py」という名前で、CotEditorのスクリプトフォルダに入れてあります。
するとこのように、ショートカットキー無しで、一覧から選択する形で実行できるようになります。
f:id:midnightseminar:20190816234554p:plain


実際やってみたら、無事置き換わってくれました。