[[R - factor と numeric の違い]] について実際の回帰分析でみてみます。 Rの回帰分析において、説明変数が numeric 型と factor 型で異なる挙動を示すことは重要なポイントです。体重変化データのサンプルを作成して、その違いを示します。 まず、サンプルデータの作成とそれぞれの回帰分析コードを示します。 このコードでは、0ヶ月、6ヶ月、12ヶ月の時点での体重データをランダムに生成し、`numeric` 型と`factor` 型の説明変数を使った回帰分析を行っています。 これらの違いを説明します: ### numeric 型 (nmonth) の場合 - 月数を連続変数として扱う - 体重変化は月数に対して直線的な関係を仮定する - 0ヶ月から12ヶ月までの間の予測も直線上で行われる ### factor 型 (fmonth) の場合 - 月数をカテゴリ変数として扱う - 各カテゴリ(0ヶ月、6ヶ月、12ヶ月)の効果を別々に推定する - 各時点での体重の平均値を個別に推定するため、直線的な関係を仮定しない ## 実際の解析 ### データセットの作成 実際に解析してみましょう。まず、データセットを作ります。 10人の体重を0ヶ月、6ヶ月、12ヶ月で測定したデータです。10人のIDは付け忘れてしまったので、どの体重がどの人かは区別しなくてよいものとします。 `fmonth` 列は、month(月数)を factor 型にしたものです。 ```R # サンプルデータの作成 # 乱数を作ってデータを作ります。これはあまり分からなくて大丈夫です。 set.seed(123) n <- 10 month <- c(rep(0, n), rep(6, n), rep(12, n)) weight <- c( rnorm(n, mean = 70, sd = 5), # 0ヶ月 rnorm(n, mean = 69, sd = 5), # 6ヶ月 rnorm(n, mean = 67, sd = 5) # 12ヶ月 ) # データフレームの作成 df <- data.frame(month = month, weight = weight) df$fmonth <- factor(df$month) # factor 型 ``` 作ったデータセットです。 ```R > df month weight fmonth 1 0 67.20 0 2 0 68.85 0 3 0 77.79 0 (中略) 15 6 66.22 6 16 6 77.93 6 17 6 71.49 6 (中略) 28 12 67.77 12 29 12 61.31 12 30 12 73.27 12 ``` ### numeric 型での回帰分析 回帰分析をします。`lm()` は回帰をする関数で、`weight ~ month` となっているのは `weight` が結果変数(従属変数)、`month` が説明変数(独立変数)ということです。`model_numeric` という変数に回帰結果がまるっとはいっています。 ```R # numeric 型での回帰分析 model_numeric <- lm(weight ~ month, data = df) ``` 回帰分析をしたので、結果を表示しておきます。 ```R # 結果表示 library(broom) tidy(model_numeric) ``` 結果は以下の通りです。 ```R > library(broom) > tidy(model_numeric) # A tibble: 2 × 5 term estimate std.error statistic p.value <chr> <dbl> <dbl> <dbl> <dbl> 1 (Intercept) 71.2 1.42 50.0 6.30e-29 2 nmonth -0.458 0.184 -2.49 1.89e- 2 ``` 以下の結果を見てみます。 ```R > tidy(model_numeric) # A tibble: 2 × 5 term estimate std.error statistic p.value <chr> <dbl> <dbl> <dbl> <dbl> 1 (Intercept) 71.2 1.42 50.0 6.30e-29 2 nmonth -0.458 0.184 -2.49 1.89e- 2 ``` この結果は、モデル `model_numeric` の結果が $y = ax+b$ でいうところの、$a$ (傾き)が `-0.458` で、$b$ (切片)が `71.2` であることを示しています。つまり $y = -0.458 x + 71.2$ です。 さて、`month` をつかった結果をグラフ化してみましょう。 モデルから予測値を計算する `emmeans` というパッケージをつかって、モデル `model_numeric` を使って 0、6、12ヶ月目の値がどうなるか予想します。 ```R # emmeans パッケージを使って予測値を計算 library(emmeans) # 数値型モデルの予測値 num_means <- emmeans(model_numeric, specs = ~ nmonth, at = list(nmonth = c(0, 6, 12))) num_results <- as.data.frame(num_means) ``` `num_results` の結果を見てみましょう。 ```R > num_results nmonth emmean SE df lower.CL upper.CL 0 71.18 1.4237 28 68.26 74.10 6 68.43 0.9004 28 66.59 70.28 12 65.68 1.4237 28 62.77 68.60 Confidence level used: 0.95 ``` 0ヶ月が `71.18`、6ヶ月が `68.43`、12ヶ月が `65.68` となっています。 たとえば、モデルである $y = -0.458 x + 71.2$ の $x$ に 6 をいれると、$-0.458 \times 6 + 71.2 = 68.4$ なので、 `emmeans` が結果をきちんと計算してくれていることがわかります。 ではグラフを作ってみましょう。ドットは元データを使っていて、青線は `num_results` を使って作られていることを理解すればOKです。 ```R # グラフ作成 library(ggplot2) # 数値型モデルのグラフ p1 <- ggplot() + geom_point(data = df, aes(x = nmonth, y = weight)) + geom_line(data = num_results, aes(x = nmonth, y = emmean), color = "blue", size = 1) + labs(title = "model using numeric", x = "Month", y = "Weight (kg)") print(p1) ``` ![[Pasted image 20250423235729.png|400]] 直線になりました。 ### factor 型での回帰分析 次に factor 型にうつります。ほぼ同じことの繰り返しになります。 ```R # factor 型での回帰分析 model_factor <- lm(weight ~ fmonth, data = df) # 結果表示 library(broom) tidy(model_factor) ``` 結果を示します。numeric 型とちがって、傾きは表示されておらず、その代わりに`fmonth` が `6` のときと `12` のときの結果が示されています。 ```R > tidy(model_factor) # A tibble: 3 × 5 term estimate std.error statistic p.value <chr> <dbl> <dbl> <dbl> <dbl> 1 (Intercept) 70.4 1.54 45.6 4.28e-27 2 fmonth6 -0.330 2.18 -0.151 8.81e- 1 3 fmonth12 -5.50 2.18 -2.52 1.80e- 2 ``` このモデルより、0ヶ月目は `(Intercept)` の `70.4` で、6ヶ月目は $70.4 + (-0.330) = 70.07$、12ヶ月目は $70.4 + (-5.50) = 64.9$ であることが分かります。 ```R # emmeans パッケージを使って予測値を計算 library(emmeans) # ファクター型モデルの予測値 factor_means <- emmeans(model_factor, specs = ~ fmonth) factor_results <- as.data.frame(factor_means) ``` モデルから計算した結果を見てみましょう。 ```R > factor_results fmonth emmean SE df lower.CL upper.CL month 0 70.37 1.542 27 67.21 73.54 0 6 70.04 1.542 27 66.88 73.21 6 12 64.88 1.542 27 61.71 68.04 12 Confidence level used: 0.95 ``` 小数点以下が四捨五入の影響ですこし違いますが、手計算で行った6ヶ月の $70.07$ と、12ヶ月の $64.9$ の値とほぼ同じことが分かります。 さて、グラフを描いてみましょう。これも先ほどと同様。ドットは元データを使っていて、青線は `factor_results` を使って作られています。 ```R # ファクター型モデルのグラフ factor_results$month <- as.numeric(as.character(factor_results$fmonth)) p2 <- ggplot() + geom_point(data = df, aes(x = month, y = weight)) + geom_line(data = factor_results, aes(x = month, y = emmean), color = "blue", size = 1) + labs(title = "model using factor", x = "Month", y = "Weight (kg)") print(p1) ``` ![[Pasted image 20250424002224.png|400]] numeric 型とはちがって 6ヶ月目、12ヶ月目が直線的ではなく、個別に求められていることがわかります。