2015-04-23 194 views
1

我一直试图在R中拟合顺序多项式回归模型,并且遇到了以下问题:poly(x)提供了一种快速方法,该函数不考虑分层原则,在转向更高的订单之前,所有的低阶条款都应该包含在模型中。R中的分层多项式回归

一个解决方案在这里,可能是入口的顺序精选到模型自己,因为我有一个玩具数据集做了下面

pred<-matrix(c(rnorm(30),rnorm(30)),ncol=2) 
y<-rnorm(30) 

polys<-poly(pred,degree=4,raw=T) 
z<-matrix(c(
#order 2 
polys[,2],polys[,6],polys[,9], 
#order 3 
polys[,3],polys[,7],polys[,10],polys[,12], 
#order 4 
polys[,4],polys[,8],polys[,11],polys[,13],polys[,14]), 
ncol=12) 

polyreg3<-function(x){ 
BICm<-rep(0,dim(x)[2]) 
for(i in 1:dim(x)[2]){ 
model<-lm(y~pred[,1]+pred[,2]+x[,1:i]) #include one additional term each time 
BICm[i]<-BIC(model) 
} 
list(BICm=BICm) 
} 

polyreg3(z) 
which.min(polyreg3(z)$BICm) 

但这是更大程度的多项式的基本上是不切实际。我在想,那么有没有办法解决这个问题,最好是通过调整我的代码?

+0

'for'循环最好在'R'中避免。去除你的循环将是一件试验。有很多关于如何做SO的例子(例如[这里是一个更通用的例子](http://stackoverflow.com/questions/4894506/avoid-two-for-loops-in-r)或[one在哪里有人正在应用lm到data.frame](http://stackoverflow.com/questions/27539033/r-apply-lm-on-each-data-frame-row)。此外,你可能希望描述你的代码找到你的瓶颈与[profr包](http://cran.r-project.org/web/packages/profr/index.html)。 –

+0

@RichardErickson感谢您的建议,虽然他们不是我最目前迫切担忧。 – JohnK

回答

1

如果我理解正确,您不仅需要原始独立变量,而且还需要给定度数可以创建的所有变量组合。

该数据除以三个因变量,原始独立变量和由model.frame()创建的额外变量,给定度数(这里为简化起见,为2)。

然后,所有额外变量的组合由combn()Map()获得,因为选择列的方式是可变的(1到#列)。

数据组是通过拟合cbind()创建和它们的变量自变量(IND )和原始自变量(原始)和额外的组合(额外)。

最后lm()是合适的,并且获得了BIC()值。

如果要求更高等级的学位,则需要进行多项试验。例如,如果度数是3,则应该应用二度和三度。

set.seed(1237) 
# independent variable 
des <- data.frame(y = rnorm(30)) 
# dependent variables 
pred<-matrix(c(rnorm(30), rnorm(30)), ncol=2) 
# model frame given degree, 4095 combinations when degree = 4, set degree = 2 for simplicity 
polys <- as.data.frame(poly(pred, degree = 2, raw = T)) 
# original independent variables 
original <- polys[,c(names(polys)[names(polys) == "1.0" | names(polys) == "0.1"])] 
# extra variables made by model.frame() 
extra <- polys[,c(names(polys)[names(polys) != "1.0" & names(polys) != "0.1"])] 
# all combinations of extra variables 
# Map() for variable q in nCq, do.call() to make list neat 
com <- do.call(c, Map(combn, ncol(extra), 1:ncol(extra), simplify = FALSE)) 
com 
[[1]] 
[1] 1 

[[2]] 
[1] 2 

[[3]] 
[1] 3 

[[4]] 
[1] 1 2 

[[5]] 
[1] 1 3 

[[6]] 
[1] 2 3 

[[7]] 
[1] 1 2 3 

# data combined, followed by fitting lm() 
bic <- lapply(com, function(x) { 
    data <- cbind(des, original, extra[, x, drop = FALSE]) 
    BIC(lm(y ~ ., data)) 
}) 

do.call(c, bic) 
[1] 100.3057 104.6485 104.8768 103.6572 103.4162 108.0270 106.7262