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

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

Rのplm::pgmm関数でError "system is computationally singular"が出まくった

{plm}パッケージのpgmmという関数でパネルデータの分析をしようとしたら、

system is computationally singular

のエラーで推定できない。
plmパッケージに例題として入っているデータとモデルではふつうに推定できたので、たぶん分析しようとしているモデルが不適切なのだろうと思い、変数やモデルの構成をいろいろ変えてみたけど、解決せず。


一般的には"system is computationally singular"というエラーは、変数間の相関が高くて多重共線性が発生している場合や、見た目上は相関が高くなくても変数の行列に一次独立でないものが混じっている(他の複数の変数の線形和で表現できるとか)場合や、サンプルサイズより変数の数が多い場合に発生する。
ところが、変数をいろいろチェックしたけど、どうもそういう問題ではなさそうに思えてきた。そもそも、学生のPCでは動いたらしいコードが自分のPCで動かないのも変なので(上記エラーはたまに、環境によって出たり出なかったりするけど)、{plm}パッケージ自体をアプデ・再インストールしようとしたところ、今度はコンパイルのところでエラーがでて、その一部を挙げると

clang: error: unsupported option '-fopenmp'

となってて進めなくなった。
これはググるといろんなところで報告されているエラーで、とりあえずこのページに書かれてあるとおりに、X-codeのxommand line toolsとclangとgfortranのアップデートをしろと言われる。
R Compiler Tools for Rcpp on macOS before R 4.0.0 | The Coatless Professor


しかしこれをやってみたところ、こんどはRcppのエラーが発生して、たとえばその一部をみると

error: no member named 'fabsf' in the global namespace

というようなことが書かれている。
このページにかかれている症状と似ている。
Odd header error due to no member named 'fabs' in the global namespace · Issue #40 · rmacoslib/r-macos-rtools · GitHub


たぶんパスの問題で、いろいろ調べてみたのだが自分の知識では解決方法がよく分からず、半日ぐらい悩んでいた。


で、結局、Rのバージョンを3.6から4.22にアップデートしたら、全て解決しました(笑)

Rで「自作関数に引数として与えたグローバル変数」を上書きする方法ってある?

Rで、自分で定義した関数内の処理のようなローカルなスコープから、グローバル変数を定義したり変更したりする操作をしたい場合は、「<<-」を使うことになっていて、

> obj1 <- c("元々1", "元々2")
> 
> myfun <- function(x){
+   obj1 <<- c(obj1, x)
+ }
> 
> myfun('追加')
> 
> print(obj1)
[1] "元々1" "元々2" "追加" 

こういうふうになるのだが、これはどのグローバル変数を上書きするかは関数定義ないに直接書き込んでしまっているので、それ自体を引数として指定したい場合のやりかたが、よく分からない。
分からないので、文字列をコードとして実行する方法を用いて、無理やり、

> append.global <- function(x, y) {
+   x.name <- as.character(eval(substitute(alist(x))))  # オブジェクト名を文字列で取得
+   code <- paste(x.name, '<<- c(', x.name, ',\"', y,'\")', sep='')
+   eval(parse(text=code))  # 文字列をコマンドとして実行
+ }
> 
> obj1 <- c("元々1", "元々2")
> append.global(obj1, '追加')
> print(obj1)
[1] "元々1" "元々2" "追加" 

というふうにしてみたのだが、もっと良い方法はないのだろうか?
関数の返り値を代入する方法だと都合が悪いことがあり、返り値を使わずに関数内の記述だけで上書きしたい。

古典を読もうとする学生に「教科書から読め」と諭す必要はないと思う

昨日、ツイッターで「大学生のための100人100冊」という、いわゆる「必読書リスト」を紹介するツイートが流れてきました。20世紀の著作を集めたものなので、「古典」というほど古くないものも多いですが、でもまあ「古典」に近いものが多いとは言えるでしょう。
 


100冊といいながら120冊載っているのですが、結構いいリストだと思いました。といっても、自分が読んだことあるものを数えてみたら33冊しかなかったので、「お前に良し悪しは判断できんだろ」と言われればその通りなのですが、読んだことがなくても聞いたことはあったり、同じ著者の別の本は読んだことがあったりするわけで、重要なものかどうかは何となく分かる……気になっています(気がするだけかも知れません)。


この種の必読書リストで一番好きなのは、柄谷行人や浅田彰らが編集した『必読書150』ってやつですね。私はポストモダンの人たちの思想は好きではないものの、古典文献リストとしてはけっこうオーソドックスなので、事あるごとに人に勧めています。人文社会科学50冊、日本文学50冊、海外文学50冊という分け方もいい。それ以外では、古典ではないですが、「サントリー学芸賞」や「吉野作造賞」の受賞作リストは外れが少ないと思います。あとは読書猿さんの「Googleが選ぶ20世紀の名著100選」かな。


ところで、「こんなリストは無視して教科書から読むべき」という意見も一緒に(複数)流れてきたのですが、個人的には、必読書リストに挑戦しようという学生に「教科書から読め」と諭す必要はないと思っています。リストに挙がっている個々の著作について、「これの岩波文庫版は翻訳が悪い」とか「これはどうせ最初の3ページで挫折するから、こっちの解説書をみながらのほうがいい」とかアドバイスすることはあるでしょう。しかし一般論として、「古典や必読書といわれる有名な本のリスト」をつぶしていこうという気概は尊いものだし、そういう意欲をもった学生には、ぜひ「最初から」その挑戦を進めてほしいですね。


「教科書から読むべき」という人は、「学生がいきなり難しい本を読んでも理解できなくて挫折するから、教科書で基礎をつくった後で取り組むべき」と考えているのでしょう。もちろん、「挫折して勉強嫌いになったら大変だ」という懸念は理解できます。ただ、私の個人的な観測範囲だと、こういうリストに挑戦するタイプの学生は、分からなかったら勝手に解説書を当たるか、巻末の解説を頼りに解読しようとするので、ほっといても大丈夫な気がします(笑)。それに、不思議なもんですが、理解できず30ページぐらいで挫折したとしても、後々、その経験が何かの気付きにつながったりすることが、意外と多いんですよね。


実際問題、必読書リストのせいで迷惑を被ったっていう若者は、存在するんですかね?読んで分からなくても、その場合たいていは読むのをやめるわけで、4年間無意味にページをなぞり続けるわけではないのだから、大きな害はないんじゃないでしょうか。それに、そもそも今の学生って、指定された教科書とネットの解説ぐらいしか読まないタイプが大半でしょう。個人的には、授業で指定された教科書を無視し、授業自体もサボって、哲学書を読みふけっているような学生を応援したいのですが、そんな学生は明らかに減っています。教科書しか読まないってのは、それはそれで大学生活としてはつまらないわけで、だから、必読書リストというものの存在意義はむしろ、「教科書しか読まないタイプの学生」に対する啓発にあると思います。


「お前ら教科書しか読んでなくて恥ずかしくないの?」的な、マウンティングというか、スノビズムの洗礼を受けるのは、なかなかいい経験です。「ニーチェ的な…」とかつい口走ると、「ニーチェの著作で一番好きなのは?」と訊かれて、「いや、ニーチェの本自体は読んだことないけど…」みたいな*1。苦痛は苦痛で、弊害も多いのですが、最近はそういう洗礼がなくなってしまって寂しい感じがします。ただ、教員がそれをやると角が立つし、教員自身もじつは全然読破してないので(笑)、リストから無言の圧力を受けるぐらいがちょうどいいですね。ちなみに、これらのリストを読破したとしても、こんどは(海外文献の場合は)「原書マウンティング」の世界が待ち受けていますので、キリはありません。


まぁ、上記のリストの中には「いきなり読むとマジで苦痛以外のなにも得られない」ものも混じってるかもしれないので、個別に判断したほうがいいのでしょう。でも、少なくとも私が読んだ33冊は大学生がいきなり読んでも問題なかったと思うし、繰り返しますが一般論として「古典・必読書リストをつぶしていく」という取り組みには、大きな意味があるという点を強調しておきたいです。


それと、たとえばウィトゲンシュタインの『論理哲学論考』やハイデガーの『存在と時間』のような本って、先に解説書を読んでいれば理解しやすいんですかね?意外と、そうでもないんじゃないでしょうか。むしろ、ちんぷんかんぷんになりながら作品そのものを読んでから、その後で解説書を当たり、さらに行ったり来たりするというのが、一番効率がいいような気がします。まぁ私はそれでも結局あまり理解できてませんが……。


また、「アリストテレスやカントやハイデガーを読む前に、教科書を読むべき」とか言われると(そもそも哲学に教科書ってあったっけという気もしますが)、なんというか、「女の子に声をかける前に恋愛の指南書を読め」というのに似た違和感があります。順序として指南書から入るのは悪くはないことも多いかも知れませんが、「このリストを読破するために、まず教科書を読もう」って、普通なりますかね?たいていの人間は、そんな悠長な段取りはできなくて、古典文献に対する興味や教養への憧れがあるなら、いきなり古典そのものを読みたいと思うのが人情です。だから、まずいきなり読んでみて、挫折するならすればいいんじゃないですかね。個人的には、そういうのが大学生活の醍醐味だと思っています。

*1:なお、部分的にしか読んでなくても、真剣に読んでいれば案外その思想家の本質は分かるので、その部分的な知識で堂々と議論すればいいと思う

MacのKarabinerが削除できずターミナルでも"su: Sorry"が出るとき

MacでUSキーボードを使っている人が、漢字かなの変換をしやすくするのに、Karabiner-Elementsというソフトがよく使われている。で、そのソフトのアップデートが上手くいかず、アンインストールしてやりなおそうとして、うまく行かなかったという報告がネット上にけっこうある。
自分も今日、その現象にハマってしまったのだが、大事なことを忘れていただけだった。


Macでアプリを削除するときは、AppCleanerとかを使うことが多いけど、Karabinerはその方法では削除できない。権限がどうのこうのという警告がでるので、ターミナルから

su rm -fr Karabiner-Elements.app


とかやるのだが、

su: Sorry


って出て先に進めない。
Mac OSでデフォルトではrootのパスワードが設定されていないために、こうなることはあるらしいのだが、
「su: Sorry」Macでrootユーザーに変更できない - いづいづブログ


Karabinerに関してはそんな問題でなく、単に、GUIで「Misc」のタブからアンインストールすればいいだけだったw
以前も同じことがあって学習したはずだったのだが、完全に忘れていて、30分ぐらい悩んでしまった……。
将来、検索で思い出せるように、ブログに書いておこうと思った。

「シャブ漬け」という比喩は世間でそれなりに使われている

吉野家の役員のくだんの発言については、特に非難したいとも擁護したいとも思わず、「生娘をシャブ漬けにしてる暇があったらうちの職場の近くに店をつくってくれ」ぐらいの感想なのだが(飲食店がほとんどないので)、「シャブ漬け」という喩えはそれなりに耳にする割に、えらい勢いで世間が怒っているなと感じた。まぁ、「生娘」のほうに怒っている人が多いのかもしれないが。
 

マーケティングの先生が、
 


とおっしゃっていて、それはそうだろうと思う一方で、「しかし『シャブ漬け』っていう比喩はそれなりに聞くけど、どんな場面だっけ?」としばらく悩んで思い出したのだが、「補助金」だな。


沖縄では、地元経済界が基地利権に依存しており、それが基地問題の政治的・社会的な解決を阻んでいることを指して、「シャブ漬け」と呼ぶことがよくあるらしい。確かに、何度か聞いたことがある気がする。

俯瞰的に見れば、基地を押し付け、基地と向き合おうとしない本土の人間がいて、沖縄からいくら声を投げ掛けても無視されてしまう状況がある。とりわけ復帰後は沖縄を黙らせるため、徹底的に各種補助金をつぎ込み既得権益層を引き込むという植民地主義的な戦略があった。「シャブ漬け」という言い方をよくするが、悪いのは明らかにシャブを打った方だ。打たれた側がそこから逃れられなくなるという構造が結果として沖縄にある。竜一君は、そのことへの苛立ちを時々口にしていた。
 
琉球新報(2015/12/17)「対談・石川竜一×初沢亜利 沖縄を撮る意味とは」より


社会学者の上野千鶴子氏は以下のインタビューで、沖縄の基地のみならず、国策プロジェクトを進めるに際して多額の補助金で地元の協力を取り付けることを、「シャブ漬け」と呼んでいた。

——沖縄、特に名護は新基地への賛否をめぐり二つに割れることを強いられてきた。地元としては自分たちが招いたわけでもない新基地に振り回されている。
 
「それは国策だから。巨額の金が動く。石原伸晃前環境相が福島について『最後は金目でしょ』と言ったが、沖縄も同じ構図だ。原発だけじゃない、三里塚(成田闘争)も八ッ場ダムも同じ。国策による補助金漬けの構図。シャブ漬け、だ」
 
——政府からすると、シャブ漬けにしているのに言うことを聞かない沖縄にいら立つのだろう。
 
「住民に権利意識が生まれ、受忍限度が下がったから。良いことだ。強姦だって昔は女たちは泣き寝入りしていた。訴えたら、落ち度があるんじゃないかと女の方が逆に責められた。今は女がガマンしないし、ガマンしなくてもよくなった。それに復帰後、沖縄県民も他府県の県民と同じだという平等意識が生まれた。だから『どうして沖縄だけがガマンしなければいけないのか』と思うようになった。当然の変化だと思う」
 
琉球新報(2014/10/29 )「<憲法・女性・沖縄 上野千鶴子さんに聞く>自らの未来決める時/金で魂買う構図変えよう」より


東海道新幹線のグリーン車に置いてある雑誌『WEDGE』では、ふるさと納税がやり玉に挙がっていた。

この2年で激増している「ふるさと納税」は、地方自治体と地方の生産者を”シャブ漬け”に追い込んでいる。
「下りると損」のチキンレースであるため、自治体や個人に自制を求めるのは不可能だ。国が適切な規制をかけるしかない。
(中略)
一方、自治体も”シャブ漬け”のようになっている。そもそも地元から得られる税収が少ない地方の自治体にとって、ふるさと納税による税収増は魅力的だ。通常の税収を超えるふるさと納税金額が集まる自治体さえ出てきており、後に続けと躍起になっている。
 
WEDGE(2016/1/20)「OPINION」より


JALが破綻した当時の前原誠司国土交通大臣と自民党の三ッ矢憲生議員のやり取りのなかで、親方日の丸の上にあぐらを書いた経営を行ってきたことや、公的資金が注ぎ込まれようとしていることが、「シャブ漬け」と呼ばれていた。
(議事録の表現を事後に修正しているかもしれないが、三ッ矢議員が「薬物中毒のどら息子みたいなもの」と言ったのを受けて、前原大臣が「シャブ漬けの息子」と言い換えている。)

○三ッ矢委員 (略)日本航空というのは、私に言わせると、薬物中毒のどら息子みたいなものですよ。生活に困りましたといって、じゃ、生活費の支援をしてあげましょうと。
(略)
○前原国務大臣 これは控えようと思ったんですが、どら息子とおっしゃいましたね。それはだれがどら息子にしたんですかと私は申し上げたいです。シャブ漬けの息子とおっしゃいましたね。だれがシャブ漬けにしたんだと。それを私はあえてここでは申し上げておきたいと思います。
 
第174回国会 国土交通委員会 第14号(平成22年4月21日(水曜日))


経済学者の金子勝教授は2021年のインタビューで、アベノミクス期の日銀の異次元緩和を指して「シャブ漬け」と呼んでいる。

「異次元策の麻薬効果、僕は『シャブ漬け』と呼ぶが、その最大の被害は産業衰退だ。産業の新陳代謝、必要な構造転換を阻んできた。特に製造業だ。その労働生産性は2000年代初めまでは世界一だったが、今や16位(OECD加盟主要31カ国中=19年データ)。あらゆる指標が落ちている。本来は潰れなければいけない電力会社がまだ生きている。原発部門が大赤字の東芝、三菱重工、日立など重電メーカーを異次元緩和で政策的に支えてきた。軽電のパナソニックも身売りの連続。自動車ですら電気自動車、自動運転になったら世界についていけない」
 
サンデー毎日(2021/8/22)「安倍・菅政治の罪と罰/7 金子勝・慶應大名誉教授が五輪後経済と産業衰退の悪夢を語る」より


古い話だが、テリー伊藤氏が小沢一郎氏について、与党の利権に「シャブ漬け」になっていると批判していた。これは補助金とは違うが。

小沢氏の態度について、演出家のテリー伊藤氏は「てっきりテーブルをひっくり返してくれると思ったのに、裏切られた思いだ。『妻とは別れる』とか言いながらセックスして、不倫関係を清算できずにいるダメな男のノリ。与党として甘い汁を吸ったらもう冷や飯食いには戻れないという一種のシャブ漬け状態」とバッサリ。
 
日刊スポーツ(1999/08/14)「自由党 小沢一郎党首 小渕恵三首相と会談し「離脱」の意思を引っ込める」


要するに、国からもらう補助金をはじめとして、「既得権益」「不労所得」「濡れ手に粟」のようなリソースに依存している状態を指して「シャブ漬け」ということがよくあるわけである。
これは「楽な方法に依存してしまうこと」を意味するので、吉野家の役員が単に「牛丼大好き」の意味で「シャブ漬け」と言ったならそれは不適切な用法だろう。仮に、「牛丼という安易な選択肢に頼ってしまい自炊しなくなる」みたいな意味であれば適切であり、大学生時代の私は生娘ではなかったが、シャブ漬けではあったことになる。


ところで、私が「シャブ漬け」という表現を「それなりに耳にする」と思ったのは、仕事で公共事業の関連の話題に触れることが多いためかも知れないので、どれだけ一般的かはわからない。どうなんでしょうね。

ステップワイズ法で特定の変数を残したい場合

私が住んでいる町では、「ステップワイズ法で、ただし特定の変数は残るようにした上で、最良のモデルを選択してほしい」と言われ、手法の妥当性を説明するのが難しいので気が進まないものの、やらざるを得ないことがあります。
ここにやり方が載っていて、


以下、ロジスティック回帰の例でやってみます。

library(dplyr)
d <- iris 

# 従属変数を2カテゴリにして、値を0,1に変換しておきます(しなくてもいいけど)
d <- d %>%
  mutate(Species = as.numeric(Species)-2) %>% 
  filter(Species != -1)

# まず、すべての変数を入れたロジスティック回帰
full.model <- glm(Species ~., family = binomial(logit), data = d, )
summary(full.model)

# AIC最小となるベストのモデルを探索
best.model.1 <- step(full.model)
summary(best.model.1)

# 特定の変数を残したい場合は、scopeの中でlowerに最小限モデルを設定する
#  (今回は結果的にフルモデルと同じものが採択される)
best.model.2 <- step(full.model, scope=list(lower=Species ~ Sepal.Length, upper=full.model))
summary(best.model.2)

Rでパワーアナリシス(検出力・検定力分析)を行う

たとえば重回帰分析とかを行って、効果が「有意ではない」ということを積極的に主張に取り入れたいときは、検出力が十分であったかを確認しなければならない。というのも、わざと出来の悪いモデルを使ったり、サンプルサイズを少なくしたりすれば、有意でないような結果を得ることは簡単だからだ。まあ検出力も、必要な効果量をどれぐらいに設定するかとか、その効果量に含まれる残差の分散の仮定の置き方などによって、ある程度恣意的に引き上げることができてしまうが、やらないよりはいいでしょう。


G*Powerというソフトが便利なのだが(MacでもWindowsでも使える)、シンプルなケースならRのpwrパッケージでできる。
解説はこのあたりを見ればいいかと。
Power Analysis in R
Quick-R: Power Analysis


G*Powerの説明は、ちょっとわかりにくいけど、たとえばこの解説。
https://www.mizumot.com/method/mizumoto-takeuchi.pdf


検出力の分析は「有意水準」「効果量」「サンプルサイズ」「検出力」のどれかを求める手続きで、ネット上や教科書の解説のほとんどは「サンプルサイズの決定」に関するものだが、べつにそれに限らず、これらのうち3つについて仮定を与えれば残りの1つを決められるので、用途は意外と広い。
効果量については、Cohenが提案している、
f^2 > 0.02 ・・・小さめの効果
f^2 > 0.15 ・・・中くらいの効果
f^2 > 0.35 ・・・大き目の効果
という基準を採用する場合は難しく考えなくてよいのだが、たとえば「回帰係数が0.1」というように具体的な値を検出したいと考えている場合は、効果量の表現に平方和が必要になって、データのばらつき具合についても仮定を置かなくてはならなくなる。


ここでは回帰分析で「有意でない」という結果が得られたときに、それを積極的に主張してよいのかどうか判断する方法を考えたいのだが、正直良くわからないので、以下のような方法で問題がある場合はご指摘いただけると助かります。


データはもう手元にあるわけで、サンプルサイズは決まっている。有意水準はたいがい0.05とかだろう。そのうえで、「検出力0.8以上になる効果量を知りたい」あるいは「◯◯という効果量を有意水準0.05で検出できる確率(検出力)を知りたい」ということになるわけである。
で、効果量について上述のCohenのような基準を考えておけば悩まくていいのだが、こんなものでは含意がよくわからないので、現実的な値で語りたくなる。


たとえば回帰分析を行った結果、x1の係数が凄く小さくて有意でなかったとする。しかしこれだけでは、「効果がない」のか「検出力が低い」のか区別がつかない。
で、「変数x1の回帰係数が少なくとも0.1ぐらいあれば、現実社会へのインプリケーションとして意味あるよね」みたいなことが言える時がある。その場合は、「真の係数が0.1だった場合に、今回と同じサンプルサイズ等でその効果が検出できる確率」を計算して、それが0.8とか0.9ぐらいあれば、「十分検出可能なのに、分析の結果有意でなかったのだから、たぶん意味があるレベルの効果は無いのだろう」と積極的に言えるようになる。「本当は0.1ぐらいの効果があるのに、検出力不足で有意にならなかった」わけではなさそうだからだ。


しかしこの計算をするには、効果量を求めるのに、回帰係数だけでなく残差についても仮定を置かないといけない。そこが面倒なのだが、残差(期待値の周りのばらつき)はもとの回帰分析と同じということにしておけば、話がわかりやすい。要するに、予測値からの乖離は同じぐらいになるという前提にして、「意味のある回帰係数」と「元のx」から「yの予測値」を出し、それに「最初の回帰分析をやったときの残差」を足して、「社会的に意味のある効果があった場合の、目的変数y」のデータを仮につくって、そのデータに対して同じように回帰分析(と分散分析)を行って、効果量を求めるわけである。期待値のまわりのばらつきが同じでも、「意味のある回帰係数」が大きければ、yの変動に占める残差の割合は小さくなるので、検出力が上がることになる。
数学が得意な人が考えればわざわざ仮のデータを作ったりしなくても求められそうだけど、自分は「説明変数同士に相関があるかもしれないからタイプIII平方和を使う」というあたりでもう考える気がなくなったので↓のようにやってみた。


以下のような関数を作っておいて、

library(car)
library(pwr)

calculate_power <- function(model, val.number, sufficient.effect, sig.level=0.05) {
  # library{car}{pwr}が必要。
  # modelにはlmの推定結果を与える。推定するときにlm(..., x=TRUE, y=TRUE, model=TRUE)としておく。
  # val.numberには、切片から数えて何個目の変数について計算するか番号を入れる。
  # sufficient.effectには、検出したい大きさの回帰係数を入れる。
  # val.number, sufficient.effectはベクトルで複数指定してもよい。
  
  coef.sufficient <- model$coefficients
  coef.sufficient[val.number] <- sufficient.effect
  
  # 回帰係数が指定した「社会的に意味ある値」だった場合のy
  y.sufficient <- t(coef.sufficient) %*% t(model$x) + model$residuals  # xに切片も入ってる
  
  # データセットの形にする
  df.sufficient <- data.frame(y.sufficient=t(y.sufficient),
                              as.data.frame(model$model[,-1]))  # modelの1列目はyになってる
  
  # 再び回帰して分散分析結果を得る
  lm.sufficient <- lm(y.sufficient ~ ., data=df.sufficient)
  anova.sufficient <- Anova(lm.sufficient, type='III')
  ss.factor.sufficient <- anova.sufficient$`Sum Sq`[val.number]
  ss.resid.sufficient <- anova.sufficient$`Sum Sq`[length(anova.sufficient$`Sum Sq`)]
  df.factor.sufficient <- anova.sufficient$Df[val.number]
  df.resid.sufficient <- anova.sufficient$Df[length(anova.sufficient$Df)]
  
  # 効果量を計算
  eta.sq <- ss.factor.sufficient / (ss.factor.sufficient + ss.resid.sufficient)
  f.sq <- eta.sq/(1-eta.sq)
  
  # この効果量を検出できる確率
  pow <- pwr.f2.test(u = df.factor.sufficient, v = df.resid.sufficient, f2 = f.sq, sig.level = sig.level)
  
  output <- list(pow$power, f.sq)
  names(output) <- c('Power', 'f2')
  return(output)
}
}


まず、目的変数y、説明変数x1〜x3を作って、回帰分析をやってみる。

> set.seed(1)
> x1 <- rnorm(100,0,1)
> x2 <- rnorm(100,5,1)
> x3 <- rnorm(100,10,1)
> y <- 2*x1 + 3*x2 + 3*x3 +rnorm(100, 0, 10)
> 
> model.1 <- lm(y~x1+x2+x3, x=T, y=T, model=T)
> summary(model.1)

Call:
lm(formula = y ~ x1 + x2 + x3, model = T, x = T, y = T)

Residuals:
     Min       1Q   Median       3Q      Max 
-25.8201  -5.2738   0.0281   6.5058  18.2364 

Coefficients:
            Estimate Std. Error t value  Pr(>|t|)    
(Intercept)  -7.1879    11.3108  -0.635    0.5266    
x1            1.4204     1.1169   1.272    0.2065    
x2            2.4506     1.0485   2.337    0.0215 *  
x3            4.0462     0.9712   4.166 0.0000677 ***
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 9.98 on 96 degrees of freedom
Multiple R-squared:  0.1981,	Adjusted R-squared:  0.1731 
F-statistic: 7.908 on 3 and 96 DF,  p-value: 0.00009087


x1の真の係数は2だけど、1.4204と推定され、pは0.2065だから有意ではない。これが、サンプルサイズ(もしくはばらつきが大きい)のせいなのか、本当に効果がないのかを考えたいなら、「x1がどの程度大きければ意味のある効果なのか」を決める必要がある。
仮にそれが1ぐらいだとすると……

> calculate_power(model=model.1, val.number=2, sufficient.effect=1)$Power
[1] 0.1457216


今回のようなサンプルサイズやばらつき具合のデータでは、「x1の係数が1」という効果が仮にあったとしても0.146ぐらいの確率でしか検出できないみたいだから、「x1に効果はない」と言うのは憚られる。
特に、あってほしい効果が検出されないなら単に「残念です、サンプルサイズを増やすか、実験計画を工夫して誤差を減らしましょう」で済むが、自分の説を主張する上で「あってほしくない効果」だった場合は、ついうっかり「どうだ、俺の言ったとおり効果はないじゃないか!」と言いたくなってしまい危険である。


ちなみに、真の値である「係数は2」は検出できるのかというと……

> calculate_power(model=model.1, val.number=2, sufficient.effect=2)$Power
[1] 0.4330289


4割ぐらいしか検出できないようだ。