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

Jacob Wegelin jacobwegelin at fastmail.fm
Thu Sep 6 20:01: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.

> 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

The following function can also be downloaded from
http://jacobwegelin.net/tmp/r-help/.

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