[R] lme(y ~ ns(x, df=splineDF)) error

Jacob Wegelin jacobwegelin at fastmail.fm
Wed Sep 26 20:14:59 CEST 2012


I would like to fit regression models of the form

y ~ ns(x, df=splineDF)

where splineDF is passed as an argument to a wrapper function.

This works fine if the regression function is lm(). But with lme(),
I get two different errors, depending on how I handle splineDF
inside the wrapper function.

A workaround is to turn the lme() command, along with the appropriate
value of splineDF, into a text string and then use
eval(parse(text=mystring)).  Is there not a more elegant solution?

The function below demonstrates this. According to the value of
WhichApproach (1, 2, or 3), it attempts one of the approaches that
does not work or the workaround using the text string.

> sessionInfo()
R version 2.15.1 (2012-06-22)
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] splines   stats     graphics  grDevices utils     datasets  methods
base

other attached packages:
[1] nlme_3.1-104  ggplot2_0.9.1

loaded via a namespace (and not attached):
   [1] colorspace_1.1-1   dichromat_1.2-4    digest_0.5.2
   grid_2.15.1        labeling_0.1
    [6] lattice_0.20-6     MASS_7.3-18        memoise_0.1
    munsell_0.3        plyr_1.7.1
    [11] proto_0.3-9.2      RColorBrewer_1.0-5 reshape2_1.2.1
    scales_0.2.1       stringr_0.6
    [16] tools_2.15.1


wrapper <-function(WhichApproach=1, splineDF=4 ){
#	Create toy dataset
nID<-25
IDnames<-LETTERS[1:nID]

longdat<-data.frame( x=rep(-10:10, nID) / 3 , ID= rep( IDnames , each=21)
)
set.seed(5)
longdat$x<-longdat$x + rnorm(nrow(longdat))/10
IDeffect<-rnorm(nID) * 20
names(IDeffect) <- IDnames
longdat$IDeffect<-IDeffect[as.character(longdat$ID)]
longdat$y<- (longdat$x
  			+ longdat$x^3
  			+ (longdat$x-1)^4  / 5
  			+ 1/(abs(longdat$x/50) + 0.02)
  			+ longdat$IDeffect
  			+ rnorm(1:nrow(longdat)) * 2
  			)
longdat<-longdat[order(longdat$x),]

library(splines)
#	Calling ns within lm works fine:
mylm<- lm( y ~ ns(x,df=splineDF), data=longdat)
longdat$lmfit<-predict(mylm)
library(ggplot2)
print(
  	ggplot(longdat, aes(x, y))
  	+ geom_point(shape=1)
  	+ geom_line(aes(x=x, y=lmfit), color="red")
)


cat("Enter to attempt lme.")
readline()
library(nlme)

if(WhichApproach==1) {
# returns: "Error in eval(expr, envir, enclos) : object 'splineDF' not found"
#
# First make sure splineDF does not exist in .GlobalEnv, else we would be in WhichApproach==2.
if(exists("splineDF", where=".GlobalEnv")) remove(list="splineDF", pos=".GlobalEnv")
mylme<-lme(fixed= y ~ ns(x, df=splineDF)
  			, random= ~ 1 | ID
  			, correlation = corAR1()
  			, data=longdat
  		)
} else if(WhichApproach==2) {
# returns: "Error in model.frame.default(formula = ~ID + y + x + splineDF, data = list( : 
# variable lengths differ (found for 'splineDF')"
assign(x="splineDF", value=splineDF, pos=".GlobalEnv")
mylme<-lme(fixed= y ~ ns(x, df=splineDF)
  			, random= ~ 1 | ID
  			, correlation = corAR1()
  			, data=longdat
  		)
} else if (WhichApproach==3) {

thecommandstring<- paste("mylme<-lme(fixed= y ~ ns(x, df=", splineDF, ") , random= ~ 1 | ID , correlation = corAR1() , data=longdat)")
thecommandstring
eval(parse(text=thecommandstring))

} else {
  	stop(paste("WhichApproach=", WhichApproach, " not valid."))
}

mylme
longdat$fullfit<-predict(mylme)

library(ggplot2)
print(
  	ggplot( longdat, aes(x,y))
  	+ geom_point(shape=1)
  	+ facet_wrap( ~ ID )
  	+ geom_line( aes(x, fullfit), color="red")
)

invisible(mylme)
}

Jacob A. Wegelin
Assistant Professor
Department of Biostatistics
Virginia Commonwealth University
830 E. Main St., Seventh Floor
P. O. Box 980032
Richmond VA 23298-0032
U.S.A.




More information about the R-help mailing list