2017-05-08 127 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