2015-04-23 226 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