如何在此线性模型中强制删除拦截或等效?

时间:2016-06-30 17:23:59

标签: r regression linear-regression lm anova

考虑下表:

DB <- data.frame(
  Y =rnorm(6),
  X1=c(T, T, F, T, F, F),
  X2=c(T, F, T, F, T, T)
)
           Y    X1    X2
1  1.8376852  TRUE  TRUE
2 -2.1173739  TRUE FALSE
3  1.3054450 FALSE  TRUE
4 -0.3476706  TRUE FALSE
5  1.3219099 FALSE  TRUE
6  0.6781750 FALSE  TRUE

我想通过两个二进制变量(TRUE或FALSE)解释我的定量变量Y,而不是截距。

这种选择的论点是,在我的研究中,我们不能同时观察X1=FALSEX2=FALSE,所以有一个没有意义这个级别的意思是0,而不是0。

拦截

m1 <- lm(Y~X1+X2, data=DB)
summary(m1)

Coefficients:
            Estimate Std. Error t value Pr(>|t|)  
(Intercept)  -1.9684     1.0590  -1.859   0.1600  
X1TRUE        0.7358     0.9032   0.815   0.4749  
X2TRUE        3.0702     0.9579   3.205   0.0491 *

没有拦截

m0 <- lm(Y~0+X1+X2, data=DB)
summary(m0)

Coefficients:
        Estimate Std. Error t value Pr(>|t|)  
X1FALSE  -1.9684     1.0590  -1.859   0.1600  
X1TRUE   -1.2325     0.5531  -2.229   0.1122  
X2TRUE    3.0702     0.9579   3.205   0.0491 *

我无法解释为什么估算变量X1 的两个系数。它似乎等于具有截距的模型中的截距系数。

相同的结果

当我们显示所有变量组合的估计时,两个模型是相同的。

DisplayLevel <- function(m){
  R <-  outer(
    unique(DB$X1),
    unique(DB$X2),
    function(a, b) predict(m,data.frame(X1=a, X2=b))
  )
  colnames(R) <- paste0('X2:', unique(DB$X2))
  rownames(R) <- paste0('X1:', unique(DB$X1))
  return(R)
}

DisplayLevel(m1)
          X2:TRUE  X2:FALSE
X1:TRUE  1.837685 -1.232522
X1:FALSE 1.101843 -1.968364

DisplayLevel(m0)
          X2:TRUE  X2:FALSE
X1:TRUE  1.837685 -1.232522
X1:FALSE 1.101843 -1.968364

所以这两个模型是等价的。

问题

我的问题是:我们可以只为第一个效果估计一个系数吗?我们可以强制R为组合X1=FALSEX2=FALSE分配0值吗?

1 个答案:

答案 0 :(得分:0)

是的,我们可以通过

DB <- as.data.frame(data.matrix(DB))
## or you can do:
## DB$X1 <- as.integer(DB$X1)
## DB$X2 <- as.integer(DB$X2)

#            Y X1 X2
# 1 -0.5059575  1  1
# 2  1.3430388  1  0
# 3 -0.2145794  0  1
# 4 -0.1795565  1  0
# 5 -0.1001907  0  1
# 6  0.7126663  0  1

## a linear model without intercept
m0 <- lm(Y ~ 0 + X1 + X2, data = DB)

DisplayLevel(m0)
#             X2:1      X2:0
# X1:1  0.15967744 0.2489237
# X1:0 -0.08924625 0.0000000

我已明确强制您将TRUE/FALSE二进制文件强制转换为数字1/0,因此lm()不会处理任何对比。

我的回答中显示的数据与您的不同,因为您在set.seed(?)之前没有使用rnorm()来获得可重复性。但这不是问题。