<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rense Nieuwenhuis &#187; stepwise</title>
	<atom:link href="http://www.rensenieuwenhuis.nl/tag/stepwise/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rensenieuwenhuis.nl</link>
	<description>&#34;The extra-ordinary lies within the curve of normality&#34;</description>
	<lastBuildDate>Thu, 12 Mar 2026 14:58:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.2.2</generator>
	<item>
		<title>R-Sessions 32: Forward.lmer: Basic stepwise function for mixed effects in R</title>
		<link>http://www.rensenieuwenhuis.nl/r-sessions-32/</link>
		<comments>http://www.rensenieuwenhuis.nl/r-sessions-32/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 10:59:03 +0000</pubDate>
		<dc:creator><![CDATA[Rense Nieuwenhuis]]></dc:creator>
				<category><![CDATA[R-Project]]></category>
		<category><![CDATA[R-Sessions]]></category>
		<category><![CDATA[forward]]></category>
		<category><![CDATA[hierarchical]]></category>
		<category><![CDATA[lme4]]></category>
		<category><![CDATA[mixed effects models]]></category>
		<category><![CDATA[multilevel]]></category>
		<category><![CDATA[stepwise]]></category>

		<guid isPermaLink="false">http://www.rensenieuwenhuis.nl/?p=897</guid>
		<description><![CDATA[Intended to be a customized solution, it may have grown to be a little more. forward.lmer is an early installment of a full stepwise function for mixed effects regression models in R-Project. I may put ...]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.rensenieuwenhuis.nl/archive/category/r-project/r-sessions/"><img title="R-Sessions" src="http://i1.wp.com/www.rensenieuwenhuis.nl/wp-content/uploads/2008/07/r-sessions.jpg?w=470" alt="" data-recalc-dims="1" /></a> </p>
<p>Intended to be a customized solution, it may have grown to be a little more. forward.lmer is an early installment of a full stepwise function for mixed effects regression models in R-Project. I may put in some work to extend it, or I may not. Nevertheless, in a &#8216;forward sense of stepwise&#8217;, I think it can be pretty useful as it is. Also, it has an interesting take on the stepwise concept, I think.<br />
<!--adsense--><br />
<span id="more-897"></span></p>
<p>Most stepwise functions (as far as I know) take a base model and a bunch of variables, and then iteratively adds and/or subtracts some variables, according to various criteria, to come to the best fitting regression model. All very interesting, but how to deal with interaction variables? And moreover: most existing functions do not work with mixed effects models ((I use the term &#8216;mixed effects model&#8217; to describe this stepwise function to refer to what is often referred to as hierarchical or multilevel regression models, as well)). </p>
<p>Built around the lme4 package in R, forward.lmer provides a forward stepwise procedure to mixed effects models. Also, it allows the user not only to enter single variables to models, but also to do the same with blocks of variables. This opens up many options: users can add the complete interactions at once (i.e. both the original and the multiplicative terms), or add these consequetively. Future development will focus on additional selection criteria for interactions, such as the criterium that at least the multiplicative term needs to be statistically significant. </p>
<p>The user provides a starting model and a set of variables to evaluate. The procedure then updates the starting model with the addition of every single variable (or block of variables). The models are ordered based on their LogLikelihood (other criteria, i.e. BIC and AIC following soon), after which the best fitting model is evaluated against one of two criteria. The first criterium is that at least one of the added parameters is statistically significant. The other criterium is that the addition of the parameters together is statistically significant. </p>
<p>There are several parameters to be specified:</p>
<ul>
<li>start.model: The starting model the procedure starts with. This can be a null-model, or a model already containing several variables. All lmer-models (i.e. logistic, poisson, linear) are supported.</li>
<li>blocks: a vector of variable names (as character strings) to be added to a model. Several variables can a concatenated within the same character string, so that these are added as a block of variables, instead of a single variables at once.</li>
<li>max.iter: The maximum number of variables that are evaluated. If max.iter is reached, the procedure stops without adding more variables. </li>
<li>sig.level: This is the p-value against which it is tested whether the new model fits better than a base model. Either sig.level or zt needs to be specified, but not both at once.</li>
<li>zt: This is either the T or Z value that is used to test whether (at least) one of the added variables is statistically significant. T values are used for linear regression, Z values for binary response models.</li>
<li>print.log: Should a log be printed? The log contains information on which variables (and on which criteria) were added in each step.</li>
</ul>
<p>The forward.lmer function returns the best fitting model (according to the given criteria). Of course, one can use this resulting model as a starting model for a new stepwise procedure.</p>
<p><code><br />
forward.lmer <- function(<br />
	start.model, blocks,<br />
	max.iter=1, sig.level=FALSE,<br />
	zt=FALSE, print.log=TRUE)<br />
	{</p>
<p>	# forward.lmer: a function for stepwise regression using lmer mixed effects models<br />
	# Author: Rense Nieuwenhuis</p>
<p>	# Initialysing internal variables<br />
	log.step <- 0<br />
	log.LL <- log.p <- log.block <- zt.temp <- log.zt <- NA<br />
	model.basis <- start.model</p>
<p>	# Maximum number of iterations cannot exceed number of blocks<br />
	if (max.iter > length(blocks)) max.iter <- length(blocks)</p>
<p>	# Setting up the outer loop<br />
	for(i in 1:max.iter)<br />
		{</p>
<p>		models <- list()</p>
<p>		# Iteratively updating the model with addition of one block of variable(s)<br />
		# Also: extracting the loglikelihood of each estimated model<br />
		for(j in 1:length(blocks))<br />
			{<br />
			models[[j]] <- update(model.basis, as.formula(paste(". ~ . + ", blocks[j])))<br />
			}</p>
<p>		LL <- unlist(lapply(models, logLik))</p>
<p>		# Ordering the models based on their loglikelihood.<br />
		# Additional selection criteria apply<br />
		for (j in order(LL, decreasing=TRUE))<br />
			{</p>
<p>			##############<br />
			############## Selection based on ANOVA-test<br />
			##############</p>
<p>			if(sig.level != FALSE)<br />
				{<br />
				if(anova(model.basis, models[[j]])[2,7] < sig.level)<br />
					{</p>
<p>					model.basis <- models[[j]]</p>
<p>					# Writing the logs<br />
					log.step <- log.step + 1<br />
					log.block[log.step] <- blocks[j]<br />
					log.LL[log.step] <- as.numeric(logLik(model.basis))<br />
					log.p[log.step] <- anova(model.basis, models[[j]])[2,7]</p>
<p>					blocks <- blocks[-j]</p>
<p>					break<br />
					}<br />
				}</p>
<p>			##############<br />
			############## Selection based significance of added variable-block<br />
			##############	</p>
<p>			if(zt != FALSE)<br />
				{<br />
				b.model <- summary(models[[j]])@coefs<br />
				diff.par <- setdiff(rownames(b.model), rownames(summary(model.basis)@coefs))<br />
				if (length(diff.par)==0) break<br />
				sig.par <- FALSE</p>
<p>				for (k in 1:length(diff.par))<br />
					{<br />
					if(abs(b.model[which(rownames(b.model)==diff.par[k]),3]) > zt)<br />
						{<br />
						sig.par <- TRUE<br />
						zt.temp <- b.model[which(rownames(b.model)==diff.par[k]),3]<br />
						break<br />
						}<br />
					}					</p>
<p>				if(sig.par==TRUE)<br />
					{<br />
					model.basis <- models[[j]]</p>
<p>					# Writing the logs<br />
					log.step <- log.step + 1<br />
					log.block[log.step] <- blocks[j]<br />
					log.LL[log.step] <- as.numeric(logLik(model.basis))<br />
					log.zt[log.step] <- zt.temp<br />
					blocks <- blocks[-j]</p>
<p>					break<br />
					}<br />
				}<br />
			}<br />
		}</p>
<p>	## Create and print log<br />
	log.df <- data.frame(log.step=1:log.step, log.block, log.LL, log.p, log.zt)<br />
	if(print.log == TRUE) print(log.df, digits=4)</p>
<p>	## Return the 'best' fitting model<br />
	return(model.basis)<br />
	} </p>
<p></code></p>
<p>As always, you're invited to use this function, or to adapt it and use that. However, it is required to make mention of this function and its author. Additionally, since I intend to continue working on this function (perhaps even evolve it to a 'package' on CRAN), I would love to hear about any experiences in using it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rensenieuwenhuis.nl/r-sessions-32/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
