4  記述統計表

前章では、一つの変数の中心や散らばりを見てきましたが、多くの場合は複数の(分析に使う全ての)変数の中心と散らばりをひとまとめにしたくなるでしょう。そのような表を記述統計表と呼びます。

この章では記述統計表の作成を学びます。加えて、データフレームの出力、スクリプト、メソッド、パイプ演算子といった基本的事項にも触れます。

4.1 簡易な方法

R
library(gapminder)

df_gap <- gapminder

summary(df_gap)
        country        continent        year         lifeExp     
 Afghanistan:  12   Africa  :624   Min.   :1952   Min.   :23.60  
 Albania    :  12   Americas:300   1st Qu.:1966   1st Qu.:48.20  
 Algeria    :  12   Asia    :396   Median :1980   Median :60.71  
 Angola     :  12   Europe  :360   Mean   :1980   Mean   :59.47  
 Argentina  :  12   Oceania : 24   3rd Qu.:1993   3rd Qu.:70.85  
 Australia  :  12                  Max.   :2007   Max.   :82.60  
 (Other)    :1632                                                
      pop              gdpPercap       
 Min.   :6.001e+04   Min.   :   241.2  
 1st Qu.:2.794e+06   1st Qu.:  1202.1  
 Median :7.024e+06   Median :  3531.8  
 Mean   :2.960e+07   Mean   :  7215.3  
 3rd Qu.:1.959e+07   3rd Qu.:  9325.5  
 Max.   :1.319e+09   Max.   :113523.1  
                                       
Python
import gapminder

df_gap = gapminder.gapminder

df_gap.describe()
             year      lifeExp           pop      gdpPercap
count  1704.00000  1704.000000  1.704000e+03    1704.000000
mean   1979.50000    59.474439  2.960121e+07    7215.327081
std      17.26533    12.917107  1.061579e+08    9857.454543
min    1952.00000    23.599000  6.001100e+04     241.165876
25%    1965.75000    48.198000  2.793664e+06    1202.060309
50%    1979.50000    60.712500  7.023596e+06    3531.846988
75%    1993.25000    70.845500  1.958522e+07    9325.462346
max    2007.00000    82.603000  1.318683e+09  113523.132900
  • e+04のような謎の文字が登場しますが、これは文字化けやエラーなどではありません。e+04\(10^4 = 10000\)を意味しています(浮動小数点数)。

このようにして気軽に記述統計表を見ることはできますが、残念ながらこのまま論文に載せることができるクオリティではありません。以下では、よりきれいな記述統計表を作成する方法を紹介します。

4.2 データフレームの作成

まず、summarytoolsというパッケージのdescr()という関数で記述統計表を作ります。初めて使う場合はパッケージのインストールを忘れないでください。

R
library(summarytools)

descr(df_gap)

Descriptive Statistics
df_gap
N: 1704

gdpPercap lifeExp pop year
Mean 7215.33 59.47 29601212.32 1979.50
Std.Dev 9857.45 12.92 106157896.74 17.27
Min 241.17 23.60 60011.00 1952.00
Q1 1201.92 48.19 2792776.00 1964.50
Median 3531.85 60.71 7023595.50 1979.50
Q3 9325.86 70.85 19593660.50 1994.50
Max 113523.13 82.60 1318683096.00 2007.00
MAD 4007.61 16.10 7841473.62 22.24
IQR 8123.40 22.65 16791557.75 27.50
CV 1.37 0.22 3.59 0.01
Skewness 3.84 -0.25 8.33 0.00
SE.Skewness 0.06 0.06 0.06 0.06
Kurtosis 27.40 -1.13 77.62 -1.22
N.Valid 1704.00 1704.00 1704.00 1704.00
Pct.Valid 100.00 100.00 100.00 100.00

このままでは項目が多いので、いくつかに絞ります。

R
library(summarytools)

descr(df_gap, stats = c("n.valid", "mean", "sd", "min", "q1", "med", "q3", "max"))

Descriptive Statistics
df_gap
N: 1704

gdpPercap lifeExp pop year
N.Valid 1704.00 1704.00 1704.00 1704.00
Mean 7215.33 59.47 29601212.32 1979.50
Std.Dev 9857.45 12.92 106157896.74 17.27
Min 241.17 23.60 60011.00 1952.00
Q1 1201.92 48.19 2792776.00 1964.50
Median 3531.85 60.71 7023595.50 1979.50
Q3 9325.86 70.85 19593660.50 1994.50
Max 113523.13 82.60 1318683096.00 2007.00

表示されるのではデータフレームではないので、出力結果をtb()関数に入れてデータフレーム化します。

R
df_sum <- descr(df_gap, stats = c("n.valid", "mean", "sd", "min", "q1", "med", "q3", "max"))
df_sum <- tb(df_sum)

print(df_sum)
# A tibble: 4 × 9
  variable  n.valid       mean          sd     min       q1    med     q3    max
  <chr>       <dbl>      <dbl>       <dbl>   <dbl>    <dbl>  <dbl>  <dbl>  <dbl>
1 gdpPercap    1704     7215.       9857.    241.    1.20e3 3.53e3 9.33e3 1.14e5
2 lifeExp      1704       59.5        12.9    23.6   4.82e1 6.07e1 7.08e1 8.26e1
3 pop          1704 29601212.  106157897.  60011     2.79e6 7.02e6 1.96e7 1.32e9
4 year         1704     1980.         17.3  1952     1.96e3 1.98e3 1.99e3 2.01e3

Pythonの場合はpandasdescribe()メソッドがデータフレームを出力します。

Python
df_sum = df_gap.describe()

print(df_sum)
             year      lifeExp           pop      gdpPercap
count  1704.00000  1704.000000  1.704000e+03    1704.000000
mean   1979.50000    59.474439  2.960121e+07    7215.327081
std      17.26533    12.917107  1.061579e+08    9857.454543
min    1952.00000    23.599000  6.001100e+04     241.165876
25%    1965.75000    48.198000  2.793664e+06    1202.060309
50%    1979.50000    60.712500  7.023596e+06    3531.846988
75%    1993.25000    70.845500  1.958522e+07    9325.462346
max    2007.00000    82.603000  1.318683e+09  113523.132900

4.2.1 転置

変数と要約統計量の位置を入れ替えたい場合は次のようにします(こちらのほうが政治学では一般的な印象を受けます)。

summarytoolsではオプションtranspose = TRUEを追加します。

R
df_sum <- descr(df_gap, stats = c("n.valid", "mean", "sd", "min", "q1", "med", "q3", "max"), transpose = TRUE)
df_sum <- tb(df_sum)

print(df_sum)
# A tibble: 4 × 9
  variable  n.valid       mean          sd     min       q1    med     q3    max
  <chr>       <dbl>      <dbl>       <dbl>   <dbl>    <dbl>  <dbl>  <dbl>  <dbl>
1 gdpPercap    1704     7215.       9857.    241.    1.20e3 3.53e3 9.33e3 1.14e5
2 lifeExp      1704       59.5        12.9    23.6   4.82e1 6.07e1 7.08e1 8.26e1
3 pop          1704 29601212.  106157897.  60011     2.79e6 7.02e6 1.96e7 1.32e9
4 year         1704     1980.         17.3  1952     1.96e3 1.98e3 1.99e3 2.01e3

Pythonの場合はtranspose()メソッドがデータフレームを転置します。

Python
df_sum = df_gap.describe()
df_sum = df_sum.transpose()

print(df_sum)
            count          mean  ...           75%           max
year       1704.0  1.979500e+03  ...  1.993250e+03  2.007000e+03
lifeExp    1704.0  5.947444e+01  ...  7.084550e+01  8.260300e+01
pop        1704.0  2.960121e+07  ...  1.958522e+07  1.318683e+09
gdpPercap  1704.0  7.215327e+03  ...  9.325462e+03  1.135231e+05

[4 rows x 8 columns]

4.3 表の出力

データフレームを論文で掲載する表として保存します。R/Pythonの外に保存する場合は、保存先としてパスを指定する必要があります。パスとはPC上の住所のようなものです。

パスは表の出力だけでなく、画像の保存やデータの読み込みの際にも必要になる重要概念なので、しっかり説明しようと思います。

4.3.1 作業ディレクトリ

まず、現在RやPythonで作業している場所を作業ディレクトリ (working directory) と言います。

  • ディレクトリとはフォルダのことです。

作業ディレクトリのパスを次のコードで確認します。

R
getwd()
Python
import os

os.getcwd()

おそらく、AAA/BBB/CCC/DDDのような文字列が表示されるはずです(Windowsの場合は/¥かもしれません)。これが作業ディレクトリのパスです。

すなわち、PCのAAAというフォルダの中のBBBの中のCCCの中のDDDで今は作業をしているという意味です。パスと住所と同じ構造をしていることが分かります。

4.3.2 保存先フォルダの作成

次に、表の出力先としてtablesというフォルダを作成します。まず、RStudio Cloudの場合、右下のFilesタブの中のFolderボタンをクリックして、Moreの中のGo To Working Directoryをクリックすると作業ディレクトリが表示されます。その中でNew Folderを選択し、tablesとフォルダ名を入力してOKをします。

Google Colaboratoryの場合、左のフォルダボタンを押すと、作業ディレクトリが開きます。しかし、Google Colaboratoryでは一定時間が経つと作業がリセットされてしまうので、Google Driveにデータを保存する方が便利です。

Google Driveの中にtablesというフォルダを作成します。次に、Colaboratoryのページの左側にフォルダのボタンがあるので、それをクリックし、上の方にあるGoogle Driveのボタンを押して、マウントします。すると、driveというフォルダが表示されます。この中のMyDriveが自身のGoogle Driveになります。先ほど作成したtablesフォルダがあることを確認してください。

自分のPC上で(ローカルの)R/Pythonを使っている場合は、まず作業ディレクトリを自分で作り、その中にtablesフォルダを作成します。

  • RStudioを使っている場合は、プロジェクトファイルを作成すると、作業ディレクトリが自動で設定されるので、おすすめします。
  • Pythonを使っている場合は、Jupyter NotebookやVScodeが自動で作業ディレクトリを設定します。

4.3.3 データフレームの保存

一つのやり方はデータフレームを.csvファイルに出力する方法です。

R
write.csv(df_sum, "tables/summary_gapminder_R.csv")
Python
df_sum.to_csv("tables/summary_gapminder_py.csv")

ファイルを保存する場合は、保存先のパスを指定する必要があります。今回は、tablesフォルダの中にsummary_gapminder_R[py].csvというファイル名で保存しようと思います。

  • tables/は「tablesというフォルダの中の」という意味です。
  • summary_gapminder_R.csvは保存するファイルの名前で、自由に決めることができます。
    • ただし、半角英数字とアンダーバー_やハイフン-のみを使い、空白は入れないことを推奨します。
  • .csvは拡張子で、今回はcsvファイルとして保存します。
  • Google Colaboratoryの場合、tables/...の前にdrive/MyDrive/を付け足します。

このように、作業ディレクトリから見たパスを相対パスと呼びます。パスを全て書く場合を絶対パスと呼びますが、使用はおすすめしません。

出力されたデータをWordなどに貼り付け、見た目をよしなにします。

4.3.4 LaTeX

texファイルとして出力する場合は例えば次のようにします。

R
library(xtable)

print(xtable(df_sum), file = "tables/summary_gapminder_R.tex", booktabs = TRUE)
Python
df_sum.to_latex("tables/summary_gapminder_py.tex")
  • パッケージjinja2をインストールしておく必要があります。

論文に載せる際は変数名を適切なものへと変更したり、キャプションなどをつけるといいでしょう。また、LaTeXのパッケージbooktabsを使うように設定しています。

4.4 スクリプト

Rで記述統計表を作成するコードをまとめてみます。

R
library(gapminder)
library(summarytools)

df_gap <- gapminder

df_sum <- descr(df_gap, stats = c("n.valid", "mean", "sd", "min", "q1", "med", "q3", "max"), transpose = TRUE)
df_sum <- tb(df_sum)

write.csv(df_sum, "tables/summary_gapminder_R.csv")

データ分析は試行錯誤なので、同じようなことを何度もすることがあります。例えば、記述統計表を作り直すということはあるでしょう。その都度、上記のようなコードをイチから書いていくのは面倒です。

そこで、コードをスクリプトに保存をします。RStudioの左上で新しくファイルを作成するボタンをクリックし、R Scriptを選択します。すると、左上にまっさらなスクリプトが登場するので、そこにコードを書き込んでいき、適宜保存をします。

実は、スクリプト上のコードはCtrl-Enterで実行することができます。なので、実際はスクリプト上にコードを書き、実行していくことになります。

Google Colaboratoryはノートブックという形式で、コードと実行結果が一体化しています。ただ、ノートブックを使わない場合は同様にPythonスクリプトを作成します(例えば、Visual Studio Codeなどを用います)。

  • ノートブックではセルごとにコードが実行されるので、適当な内容ごとにセルを区切ってコードを書くようにしましょう。

4.5 パイプ演算子

Pythonで記述統計表を作成するコードをまとめます。

Python
import gapminder

df_gap = gapminder.gapminder

df_sum = df_gap.describe()
df_sum = df_sum.transpose()

df_sum.to_csv("tables/summary_gapminder_py.csv")

ところで、Pythonでは特定の種類のオブジェクトに限定した処理はメソッドとして提供されています。そして、メソッドは連結して書くことができます。

例えば上記のコードは以下のようになります。

Python
import gapminder

df_gap = gapminder.gapminder

df_gap.describe().transpose().to_csv("tables/summary_gapminder_py.csv")

Rではパイプ演算子と呼ばれるものを使って、同様に書くことができます。パイプ演算子とは%>%もしくは|>のことで、左側の内容を右側の関数の最初の入力として渡します。

  • 例えば、a |> f(...)というのはf(a, ...)と等価です。

パイプ演算子を使うと、次のようにまとめて書くことができます。

R
library(gapminder)
library(summarytools)

df_gap <- gapminder

df_gap |> 
    descr(stats = c("n.valid", "mean", "sd", "min", "q1", "med", "q3", "max"), transpose = TRUE) |> 
    tb() |> 
    write.csv("tables/summary_gapminder_R.csv")

メソッドやパイプ演算子で連結させて書くか、処理を一つずつ行ってオブジェクトに代入して書くかは見やすさや個人の好みに応じて決めればよいと思います。

2つのパイプ演算子

Rにはパイプ演算子が2つあります。まず、%>%というのはmagrittr(より一般的にはtidyverse)のパイプ演算子で、先に登場しました。その後、Rでも標準のパイプ演算子として|>が導入されました。

僕が理解する範囲ではどちらも機能は変わらないので、好きな方を使えば良いと思います(使わなくてもいいと思います)。ただ、他の人が書いたコードにこれらが登場しても混乱しないようにしましょう。

Pythonでは()でくくって、コードを改行することができます。

Python
import gapminder

df_gap = gapminder.gapminder

(
    df_gap
    .describe()
    .transpose()
    .to_csv("tables/summary_gapminder_py.csv")
)