lm() 在使用 poly() 并将预测变量设置为因子时中断

lm() breaks when using poly() with predictors set up as factors

我正在尝试对分类预测变量和连续结果变量之间的关系建模。为此,我使用 lm()。由于它是分类变量,正确的做法是将其转换为因子变量类型。但是,当使用 poly() 作为预测变量的回归项时 将预测变量设置为因子时会导致 lm() 失效。另一方面,如果我 运行 lm() 不使用 poly()(但确实保留预测变量作为因子) 保留 poly()但不将预测变量转换为一个因子(让它是数字)——然后 lm() 不会中断。我不明白它为什么会坏,我不明白如果它没有坏,我是否可以相信结果。

数据

50 名篮球运动员的数据。一列 (PosCode) 是关于玩家在游戏中的位置,另一列 (Height) 是玩家的身高。

data <-
structure(list(Player = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 
44, 45, 46, 47, 48, 49, 50), PosCode = c(3, 3, 4, 1, 4, 1, 3, 
1, 2, 2, 4, 1, 5, 5, 2, 1, 2, 5, 4, 4, 5, 4, 4, 4, 2, 3, 2, 3, 
1, 1, 2, 4, 1, 2, 3, 1, 5, 4, 3, 4, 4, 1, 1, 4, 5, 1, 1, 1, 5, 
2), Height = c(176.1, 179.1, 183.1, 169.7, 177.3, 179, 176.4, 
174.9, 180.2, 176.5, 178.6, 167.9, 183.4, 166.2, 189.5, 171.9, 
188.5, 172.6, 167.7, 172.6, 186.9, 163.8, 179.3, 165.4, 182.2, 
166.1, 176.8, 171.9, 173.8, 163, 172.5, 184.9, 170.4, 170.6, 
166.8, 172.6, 184.3, 163.3, 182.4, 165.8, 173.4, 182.1, 172.9, 
184.9, 173.2, 185.8, 161.4, 186, 178.4, 170.7)), row.names = c(NA, 
-50L), class = c("tbl_df", "tbl", "data.frame"))


> data
## # A tibble: 50 x 3
##    Player PosCode Height
##    <dbl>   <dbl>  <dbl>
##  1      1       3   176.
##  2      2       3   179.
##  3      3       4   183.
##  4      4       1   170.
##  5      5       4   177.
##  6      6       1   179 
##  7      7       3   176.
##  8      8       1   175.
##  9      9       2   180.
## 10     10       2   176.
## # ... with 40 more rows

数据建模

我想知道我是否可以根据球员在比赛中的位置来预测他们的身高。由于位置是分类的(有 5 个可能的位置),因此该变量应该是因子类型,具有 5 个水平。

library(tidyverse)
library(magrittr) 

data %<>% mutate_at(vars(PosCode), ~ as.factor(.)) ## convert PosCode from dbl to fct

使用 lm() 建模 不使用 poly()

lm(Height ~ PosCode, data = data)

## Call:
## lm(formula = Height ~ PosCode, data = data)
## 
## Coefficients:
## (Intercept)     PosCode2     PosCode3     PosCode4     PosCode5  
##    173.6714       4.9397       0.4429       0.1824       4.1857  

使用lm()poly()

建模
lm(Height ~ poly(PosCode ,1), data = data)

## Error in qr.default(X) : NA/NaN/Inf in foreign function call (arg 1)
## In addition: Warning messages:
## 1: In mean.default(x) : argument is not numeric or logical: returning NA
## 2: In Ops.factor(x, xbar) : ‘-’ not meaningful for factors

如果预测变量不是一个因素,那么无论 poly()

都没有问题
## convert PosCode from fct back to dbl
data %<>% mutate_at(vars(PosCode), ~ as.double(.)) 

## lm() without poly()
lm(Height ~ PosCode, data = data)

Call:
lm(formula = Height ~ PosCode, data = data)

## Coefficients:
## (Intercept)      PosCode  
##   174.3848       0.3112 


## lm() with poly() 
lm(Height ~ poly(PosCode ,1), data = data)

## Call:
## lm(formula = Height ~ poly(PosCode, 1), data = data)

## Coefficients:
##      (Intercept)  poly(PosCode, 1)  
##          175.256             3.173 

但显然,将 PosCode 视为 dbl 而不是 fct 会以错误的方式改变模型。

底线

我不明白为什么在 lm() 中包含 poly() 会在预测变量设置为因子变量时破坏它。

来自 help("poly"):

x a numeric vector at which to evaluate the polynomial.

因此,您不能在 poly() 中使用因子。这是意料之中的,因为分类变量(即因子)必须重新编码,例如,转换为虚拟变量。比如说,对整个分类变量或编码(虚拟)变量都具有二次效应是没有意义的。 (从实质性的角度来看这没有意义,但是从不了解统计的角度来看,对一个只有 0 和 1 的虚拟变量求平方也没有多大意义。)

您可以看到 lm() 重新编码了您的因子,因为您在第一个模型中获得了变量 PosCode 的四个系数(比类别数少一个)。

最后,poly() 没有多大用处,除非您将其参数 degree 设置为大于 1 的值