[[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ヶ月目が直線的ではなく、個別に求められていることがわかります。