2017-05-08 56 views
2

我有一個data.frame中的氣候數據的數據集(列是測量站,行表示測量的時間),我試圖在Yeo-Johnson變換中找到合適的lambda值以限制主成分分析中的偏態影響。R問題:執行LM然後boxcox找到正確的lambda值

顯然,第一步是獲取登錄可能性找到最好的λ:我用以下,其中i是列索引:

getYeoJohsnonLambda <- function(myClimateData,cols,lambda_min, lambda_max,eps) 
... 
lambda <- seq(lambda_min,lambda_max,eps) 
for(i in cols) 
    { 
    formula <- as.formula(paste("myClimateData$",colnames(myClimateData)[i],"~1")) 
    currentModel <- lm(formula,myClimateData) 
    print(currentModel) 
    myboxCox <- boxCox(currentModel, lambda = lambda ,family="yjPower", plotit = FALSE) 
    ... 
    } 

當我試圖把它的這可能是climateData時間序列,例如:

`climateData <-data.frame(c(8.2,6.83,5.46,4.1,3.73,3.36,3,3,3,3,3.7),c(0,0.66,1.33,2,2,2,2,2,2,2,1.6))` 

我得到這個錯誤:Error in is.data.frame(data) : object 'myClimateData' not found

這很奇怪,因爲LM似乎找到它,並返回一個科爾ect fit和myClimateData應該被找到,因爲它是函數的參數之一,對吧?

+0

問題在於你如何形成你的公式:'公式< - as.formula(paste(「myClimateData $」,colnames(myClimateData)[i],「〜1」))''。相反,嘗試類似'lm(as.formula(paste(colnames(climateData)[1],「〜1」)),data = myClimateData) –

+0

我試圖改變爲: \t \t'currentModel < - lm as.formula(膏(colnames(myClimateData)[I], 「〜1」)),數據= myClimateData) \t \t打印(currentModel) \t \t myboxCox < - boxCox(currentModel,λ-=拉姆達,家族= 「yjPower」,plotit = FALSE) 但我仍然有同樣的錯誤:在BoxCox行中發現is.data.frame(x):object'myClimateData'找不到對象'。 這真的很奇怪,因爲「myClimateData」是函數參數之一。 – qwartz

回答

1

可悲的是,似乎問題來自於功能boxCox而不是你getYeoJohsnonLambda功能。由於BrodieG指出in a related question,此功能使用parent.frame作爲eval的參數,這在文檔中被認爲是不好的做法。要解決這個

一種方法是建立呼叫之前的車型,如Adam Quek的回答提示:

library(car) 

climateData <- data.frame(c(8.2,6.83,5.46,4.1,3.73,3.36,3,3,3,3,3.7),c(0,0.66,1.33,2,2,2,2,2,2,2,1.6)) 
names(climateData) <- c("a","b") 

modelList <- list() 
for(k in 1:ncol(climateData)) { 
    modelList[[k]] <- lm(as.formula(paste0(names(climateData)[k],"~1")),data=climateData) 
} 

getYeoJohnsonLambda <- function(myClimateData, cols, lambda_min, lambda_max, eps) 
{ 
    #Recommended values for lambda_min = -0.5 and lambda_max = 2.0, eps = 0.1 
    myboxCox <- list() 
    lmd <- seq(lambda_min,lambda_max,eps) 
    for(i in cols) 
    { 
    cat("Creating model for column # ",i,"\n") 
    currentModel <- modelList[[i]] 
    myboxCox[[i]] <- boxCox(currentModel, lambda = lmd ,family="yjPower", plotit = FALSE) 

    } 
    return(myboxCox) 
} 

test <- getYeoJohnsonLambda(climateData,c(1,2) ,-0.5,2,0.1) 

其他解決方案(可以說是清潔劑):在使用yeo.johnsonVGAM

library(VGAM) 

getYeoJohnsonLambda_VGAM <- function(myClimateData, cols, lambda_min, lambda_max, eps) 
{ 
    #Recommended values for lambda_min = -0.5 and lambda_max = 2.0, eps = 0.1 
    myboxCox <- list() 
    lmd <- seq(lambda_min,lambda_max,eps) 
    return(apply(climateData,2,yeo.johnson,lambda=lmd)) 
} 

test2 <- getYeoJohnsonLambda_VGAM(climateData,c(1,2) ,-0.5,2,0.1) 
+0

我覺得Antoine真的很愚蠢,因爲事實證明,汽車包已經有了一個「powerTransform」功能,它完全符合我的要求。抱歉給你帶來不便... – qwartz

0

這裏有沒有getYeoJohsnonLambda故障排除功能的解決方案:

iris.dat <- iris[-5] 
vars <- names(iris.dat) 
lmd <- seq(.1, 1, .1) #lambda_min, lambda_max, eps 

all.form <- lapply(vars, function(x) as.formula(paste0(x, "~ 1"))) 
all.lm <- lapply(all.form, lm, data=iris.dat) 

library(MASS) 
all.bcox <- lapply(all.form, boxcox, data=iris.dat, 
      lambda=lmd, family="yjPower", plotit=FALSE) 
+0

看起來,這會產生「boxcox.default中的錯誤(X [[i]],...):響應變量必須爲正值 另外:警告消息: 在lm.fit(x,y,offset =偏移量,singular.ok = singular.ok,...): 額外參數'家族'將被忽略「 事實上:我的變量具有零值(這就是爲什麼我使用Yeo-Johnson而不是Box-Cox)。 – qwartz

+0

更詳細的看堆棧跟蹤表明它是「eval(expr,envir,enclos)」的問題,指向在http://stackoverflow.com/questions/22617354/object-not-found遇到的問題類型用戶定義的函數評估函數...我嘗試使用「noquote」,但無濟於事。 – qwartz

相關問題