0 基礎的な統計と分布の検定
このページでは、特定の群のデータだけ抜き出してデータテーブルのオブジェクトを作ったり、基本統計値を出したりします。
まず、以下に必要なスクリプトの全てを貼っておきます。
code:r
# ---------- preparation in advanca 事前準備--------------------------------------------------
# Install packages if not installed 必要なパッケージが無けれな自動でインストール-----
if(!require("dplyr")) install.packages("dplyr") #データ整形に使う if(!require("car")) install.packages("car") #needed for Levene's test # clear R's brain 一度参照したリストもしくは変数を次の作業で消す-----
rm(list = ls())
# Load libraries 必要なパッケージの読み込み-----
library(car) #needed for Levene's test # Data input 今後以下のパスからデータを自動で読み込みする場合-----
library(readr)
CanRsample <- read.csv(file.choose()) #Run and choose CanRsample2021.csv # # ----------prep done 準備だん------------------------------------------------------------
# データ整形する場合----------
# 【0】基本的な統計と下準備 preparation for basic stats----------------------------
summarise(
mean_Temp_year = mean(aveTemp_year),
Var_Temp_year = var(aveTemp_year),
SD_Temp_year = sd(aveTemp_year),
SEM_Temp_year = sd(aveTemp_year)/sqrt(length(aveTemp_year)),
Median_Temp_year = median(aveTemp_year)
)
dSendai <-filter(CanRsample, place == "Sendai") #(元データ, 抽出したい群名がある列名 == "群名") dTokyo <-filter(CanRsample, place == "Tokyo")
dKagoshima <-filter(CanRsample, place == "Kagoshima")
shapiro.test(dTokyo$aveTemp_year)
shapiro.test(dKagoshima$aveTemp_year)
leveneTest(CanRsample$aveTemp_year ~ factor(CanRsample$place)) #(従属変数 ~ 独立変数) leveneTest(dKago_Sen$aveTemp_year ~ factor(dKago_Sen$place))
dKago_Tok <-filter(CanRsample, place == "Kagoshima" | place == "Tokyo")
dSen_Tok <-filter(CanRsample, place == "Sendai" | place == "Tokyo")
最初なので、細かいとこをも、小分けにして説明します。
-----preparation in advanca 事前準備-----
と書いてあるところで、必要なパッケージを読み込んだり、データを読み込んだりしてます。
パッケージ:今回読み込んでるパッケージですが、例えば dplyr データ整形につかっています。Excelのフィルター機能みたいなもの使いたい時に必要です。他に carパッケージも入れていますが、後述します。
データ読み込み:"CanRsample <- read.csv(file.choose()) " とうところで、データを読み込んで、CanRsampleというデータセットとしてオブジェクト化しています。file.choose() を使うと、日頃PCのソフトウェア上でファイルを選ぶ時みたいにフォルダの中をブラウズしてくれるんですが、これを使うと、スクリプトに「どのcsvファイルを使ったか」の記録が残らないので、僕はコメントとして記載しています。
【基本統計値】
summarise() という関数で平均値とか標準偏差とかを求めるスクリプトが書いてあります。
先ほどCanRsample という名前でオブジェクトかしたデータをデータをパス(%>%)で別の関すに送っています。こういうことをするために、オブジェクトは便利です。
このデータを一旦、group_by(place) という関数に送っています。こうすると、placeという変数にある水準の、SendaiとTokyoとKagoshimaという地名別(群ごと)のデータセットを作ってくれて、これを最後に summarise() に送っているので、群ごとの基本統計値を出してくれています。
これを実行した結果が、以下です。
code:r
# A tibble: 3 × 6
place mean_Temp_year Var_Temp_year SD_Temp_year SEM_Temp_year Median_Temp_year
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Kagoshima 27.3 10.4 3.22 1.02 27.6
2 Sendai 15.2 2.34 1.53 0.483 15.4
3 Tokyo 21.8 5.71 2.39 0.756 21.8
左から年間気温についての平均値、分散、標準偏差、標準誤差(SEM)、中央値を計算するスクリプトにしています。
"*_Temp_year" などの部分は任意なので、お好みの名前を付けられます。
【特定の群のデータだけ抽出して検定する】
スクリプトの後半部分では、まず、SendaiとTokyoとKagoshimaの、1群のみのデータをもつオブジェクトを、filter() 関数で作っています。filter関数がやっていることは、Excelのフィルターと同じです。スプリプとのコメントにあるように、
filter(元データ, 抽出したい群名がある列名 == "群名")
という書き方です。Sendaiのデータを抽出するなら、
filter(CanRsample, place == "Sendai")
ということになります。上記スクリプトではフィルターで抽出したデータを、dSendaiというオブジェクトにまとめています。
さて、なんでこんな1群だけのデータセットをまとめているかというと、
例えば正規性の検定である Shapiro-Wilk test では、検定したい群の数値だけが含まれたデータセットにしていないと読み込んでくれないからです。
書き方は、コメントにあるように
shapiro.test(使いたい群のオブジェクト$調べたい値の列名)
です。
検定の結果は以下です。
code:r
Shapiro-Wilk normality test
data: dSendai$aveTemp_year
W = 0.91221, p-value = 0.2965
shapiro.test(dTokyo$aveTemp_year)
Shapiro-Wilk normality test
data: dTokyo$aveTemp_year
W = 0.95657, p-value = 0.7462
shapiro.test(dKagoshima$aveTemp_year)
Shapiro-Wilk normality test
data: dKagoshima$aveTemp_year
W = 0.96566, p-value = 0.848
シャピロ–ウィルク検定の帰無仮説は「データは正規分布している」なので、有意なときに「正規分布しているとは言えない」となるので、今回は、全ての群で正規性が認めらると判断することになります。
正規性の検定の他にも、等分散性の検定もやりたくなりますよね。はじめにこのサイトについて で書いたように、等分散性の検定をせずに、なるべくWelch系の検定を最初から使ってしまうという方針の方が良いのですが、ここではRの使いかたの練習として、Levenの検定をやってみます。 僕のスクリプトでは、car というパッケージに入っている leveneTest() を使っています。 わざわざ car を使わずとも、デフォルトで使える levene.test() という関数もあるのですが、僕は前者のデータの読み込み方が好きなので、そちらを選んだような記憶。
書き方としては、
leveneTest(CanRsample$aveTemp_year ~ factor(CanRsample$place))
となります。
"検定の関数(従属変数 ~ 独立変数)" という書き方はよくあります。
$は "(用いるデータセット$変数を示す列名)" という書き方で用います。なでの、上の関数の読み方はとしては、
「CanRsampleというデータセットの年平均気温の分散が、placeという列名で示した群間で等しいと言えるかどうか検定する」みたいな感じです。
今回の検定結果は、有意ではないので、各群は等分散であるとみなせる結果なんですが、もし有意だった場合には、どの群とどの群で分散が異なったのか、わからなくなってしまいますね。
なので、最後の部分のスクリプトでは、
filter(用いるデータ, 変数となる列名 == "水準A" | 変数となる列名 == "水準B")
を用いて、AもしくはB、すなわち「A群のデータとB群のデータを抽出」という形で2群の間の分散を比較しています。
" | "は、「or」的に使います。
basicの実践の最初のページなので、ちょっと詳しく解説してしまいましたが、いかがでしたでしょうか?