Paruelo and Lauenroth (1996) analyzed the geographic distribution and the effects of climate variables on the relative abundance of a number of plant functional types (PFTs) including shrubs, forbs, succulents (e.g. cacti), C3 grasses and C4 grasses. There were 73 sites across North America. The response variable we will focus on is the relative abundance of C3 plants and there were six potential predictors: the latitude in centesimal degrees (LAT), the longitude in centesimal degrees (LONG), the mean annual precipitation in mm (MAP), the mean annual temperature in °C (MAT), the proportion of MAP that fell in June, July and August (JJAMAP) and the proportion of MAP that fell in December, January and February (DJFMAP).

This is an example from the first edition; the data file is here

Paruelo, J. M. & Lauenroth, W. K. (1996). Relative abundance of plant functional types in grasslands and shrublands of North America. Ecological Applications, 6, 1212-24.

Preliminaries

First, load the required packages (car, lm.beta, reghelper, Rmisc and rgl)

Import paruelo data file (paruelo.csv)

paruelo <- read.csv("../data/paruelo.csv")
head(paruelo,10)

Diagnostic checks

We will use the scatterplotMatrix function from the car package

scatterplotMatrix(~c3+lat+long+map+mat+jjamap+djfmap, data=paruelo, cex=0.33, regLine=FALSE, diagonal=list(method='boxplot'))

C3 positively skewed but not too bad; no obvious non-linearities

Now check for collinearity among all predictors - correlations and VIFs

cor(paruelo[,c('lat','long','map','mat','jjamap','djfmap')])
           lat    long    map      mat  jjamap   djfmap
lat     1.0000  0.0966 -0.247 -0.83859  0.0742 -0.06512
long    0.0966  1.0000 -0.734 -0.21311 -0.4916  0.77074
map    -0.2465 -0.7337  1.000  0.35509  0.1123 -0.40451
mat    -0.8386 -0.2131  0.355  1.00000 -0.0808  0.00148
jjamap  0.0742 -0.4916  0.112 -0.08077  1.0000 -0.79154
djfmap -0.0651  0.7707 -0.405  0.00148 -0.7915  1.00000
vif(lm(c3~lat+long+map+mat+jjamap+djfmap, data=paruelo))
   lat   long    map    mat jjamap djfmap 
  3.50   5.27   2.80   3.74   3.16   5.71 

Obvious collinearity with environmental variables tending to be correlated strongly with lat or long, so we’ll split predictors into 2 groups, one with lat and long

First model c3 against lat and long and lat*long and check for collinearity

vif(lm(c3~lat+long+lat*long, data=paruelo))
there are higher-order terms (interactions) in this model
consider setting type = 'predictor'; see ?vif
     lat     long lat:long 
   307.7     66.8    400.9 

VIFs very high indicating obvious collinearity as expected with interaction term

Run uncentred model

paruelo.lm <- lm(c3~lat+long+lat*long, data=paruelo)

Get regression diagnostics (residual plot and Cooks D)

plot(paruelo.lm)

augment(paruelo.lm)

Display results of model fitting

glance(paruelo.lm)
tidy(paruelo.lm, conf.int=TRUE)

Get standardized regression coefficients, use lm.beta function from lm.beta package

lm.beta.paruelo <- lm.beta(paruelo.lm)
tidy(lm.beta.paruelo, conf.int=TRUE)

Centre predictors and refit model

paruelo$clat <- scale(paruelo$lat, center=TRUE, scale=FALSE)
paruelo$clong <- scale(paruelo$long, center=TRUE, scale=FALSE)
paruelo1.lm <- lm(c3~clat+clong+clat*clong, data=paruelo)

Recheck collinearity

vif(lm(c3~clat+clong+clat*clong, data=paruelo))
there are higher-order terms (interactions) in this model
consider setting type = 'predictor'; see ?vif
      clat      clong clat:clong 
      1.21       1.02       1.22 

Regression diagnostics (residual plot and Cooks D)

plot(paruelo1.lm)

augment(paruelo1.lm)

Diagnostics look better now

Display results of model fitting

glance(paruelo1.lm)
tidy(paruelo1.lm, conf.int=TRUE)

Get standardized regression coefficients, use lm.beta function from lm.beta package

lm.beta(paruelo1.lm)

Call:
lm(formula = c3 ~ clat + clong + clat * clong, data = paruelo)

Standardized Coefficients::
(Intercept)        clat       clong  clat:clong 
         NA    0.770191    0.000703    0.249471 

Standardise predictors and refit model

paruelo$slat <- scale(paruelo$lat, center=TRUE, scale=TRUE)
paruelo$slong <- scale(paruelo$long, center=TRUE, scale=TRUE)
paruelo2.lm <- lm(c3~slat+slong+slat*slong, data=paruelo)

Recheck collinearity

vif(lm(c3~slat+slong+slat*slong, data=paruelo))
there are higher-order terms (interactions) in this model
consider setting type = 'predictor'; see ?vif
      slat      slong slat:slong 
      1.21       1.02       1.22 

Regression diagnostics (residual plot and Cooks D)

plot(paruelo2.lm)

augment(paruelo2.lm)

Display results of model fitting

glance(paruelo2.lm)
tidy(paruelo2.lm, conf.int=TRUE)

Get standardised regression coefficients, use lm.beta function from lm.beta package

lm.beta(paruelo2.lm)

Call:
lm(formula = c3 ~ slat + slong + slat * slong, data = paruelo)

Standardized Coefficients::
(Intercept)        slat       slong  slat:slong 
         NA    0.770191    0.000703    0.249471 

3d scatterplot with smoothing surface

Note on mac OS - need xquartz installed. Graphic opens in separate window in Mac/Xquartz; haven’t checked on other operating systems.

Rotate the graph using the mouse or cursor keys

scatter3d(c3~lat+long, grid = FALSE, fit = "smooth", data=paruelo)

Examine simple slopes using reghelper package

simple_slopes(paruelo.lm)
        lat       long Test Estimate Std. Error t value df Pr(>|t|) Sig.
1 34.801242     sstest        -0.010      0.005  -2.039 69   0.0453    *
2 40.104247     sstest         0.000      0.004   0.008 69   0.9935     
3 45.407251     sstest         0.010      0.005   1.848 69   0.0689    .
4    sstest   99.96472         0.026      0.005   5.159 69 2.27e-06  ***
5    sstest 106.400137         0.038      0.005   8.198 69 8.69e-12  ***
6    sstest 112.835554         0.050      0.008   6.484 69 1.13e-08  ***
LS0tCnRpdGxlOiAiUUsgQm94IDguOCIKCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRoZW1lOiBmbGF0bHkKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKClBhcnVlbG8gYW5kIExhdWVucm90aCAoMTk5NikgYW5hbHl6ZWQgdGhlIGdlb2dyYXBoaWMgZGlzdHJpYnV0aW9uIGFuZCB0aGUgZWZmZWN0cyBvZiBjbGltYXRlIHZhcmlhYmxlcyBvbiB0aGUgcmVsYXRpdmUgYWJ1bmRhbmNlIG9mIGEgbnVtYmVyIG9mIHBsYW50IGZ1bmN0aW9uYWwgdHlwZXMgKFBGVHMpIGluY2x1ZGluZyBzaHJ1YnMsIGZvcmJzLCBzdWNjdWxlbnRzIChlLmcuIGNhY3RpKSwgQzMgZ3Jhc3NlcyBhbmQgQzQgZ3Jhc3Nlcy4gVGhlcmUgd2VyZSA3MyBzaXRlcyBhY3Jvc3MgTm9ydGggQW1lcmljYS4gVGhlIHJlc3BvbnNlIHZhcmlhYmxlIHdlIHdpbGwgZm9jdXMgb24gaXMgdGhlIHJlbGF0aXZlIGFidW5kYW5jZSBvZiBDMyBwbGFudHMgYW5kIHRoZXJlIHdlcmUgc2l4IHBvdGVudGlhbCBwcmVkaWN0b3JzOiB0aGUgbGF0aXR1ZGUgaW4gY2VudGVzaW1hbCBkZWdyZWVzIChMQVQpLCB0aGUgbG9uZ2l0dWRlIGluIGNlbnRlc2ltYWwgZGVncmVlcyAoTE9ORyksIHRoZSBtZWFuIGFubnVhbCBwcmVjaXBpdGF0aW9uIGluIG1tIChNQVApLCB0aGUgbWVhbiBhbm51YWwgdGVtcGVyYXR1cmUgaW4gwrBDIChNQVQpLCB0aGUgcHJvcG9ydGlvbiBvZiBNQVAgdGhhdCBmZWxsIGluIEp1bmUsIEp1bHkgYW5kIEF1Z3VzdCAoSkpBTUFQKSBhbmQgdGhlIHByb3BvcnRpb24gb2YgTUFQIHRoYXQgZmVsbCBpbiBEZWNlbWJlciwgSmFudWFyeSBhbmQgRmVicnVhcnkgKERKRk1BUCkuCgpUaGlzIGlzIGFuIGV4YW1wbGUgZnJvbSB0aGUgZmlyc3QgZWRpdGlvbjsgdGhlIGRhdGEgZmlsZSBpcyBbaGVyZV0oZGF0YS9wYXJ1ZWxvLmNzdikKClBhcnVlbG8sIEouIE0uICYgTGF1ZW5yb3RoLCBXLiBLLiAoMTk5NikuIFJlbGF0aXZlIGFidW5kYW5jZSBvZiBwbGFudCBmdW5jdGlvbmFsIHR5cGVzIGluIGdyYXNzbGFuZHMgYW5kIHNocnVibGFuZHMgb2YgTm9ydGggQW1lcmljYS4gKkVjb2xvZ2ljYWwgQXBwbGljYXRpb25zKiwgNiwgMTIxMi0yNC4KCiMjIyBQcmVsaW1pbmFyaWVzCgpGaXJzdCwgbG9hZCB0aGUgcmVxdWlyZWQgcGFja2FnZXMgKGNhciwgbG0uYmV0YSwgcmVnaGVscGVyLCBSbWlzYyBhbmQgcmdsKQoKYGBge3IgaW5jbHVkZT1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGVycm9yPVRSVUV9CnNvdXJjZSgiLi4vUi9saWJyYXJpZXMuUiIpICAgI1RoaXMgaXMgdGhlIGNvbW1vbiBsaWJyYXJ5CmxpYnJhcnkobG0uYmV0YSkKbGlicmFyeShyZWdoZWxwZXIpCmxpYnJhcnkocmdsKQpgYGAKCkltcG9ydCBwYXJ1ZWxvIGRhdGEgZmlsZSAocGFydWVsby5jc3YpCgpgYGB7cn0KcGFydWVsbyA8LSByZWFkLmNzdigiLi4vZGF0YS9wYXJ1ZWxvLmNzdiIpCmhlYWQocGFydWVsbywxMCkKYGBgCgojIyMgRGlhZ25vc3RpYyBjaGVja3MKCldlIHdpbGwgdXNlIHRoZSBzY2F0dGVycGxvdE1hdHJpeCBmdW5jdGlvbiBmcm9tIHRoZSBjYXIgcGFja2FnZQoKYGBge3IgfQpzY2F0dGVycGxvdE1hdHJpeCh+YzMrbGF0K2xvbmcrbWFwK21hdCtqamFtYXArZGpmbWFwLCBkYXRhPXBhcnVlbG8sIGNleD0wLjMzLCByZWdMaW5lPUZBTFNFLCBkaWFnb25hbD1saXN0KG1ldGhvZD0nYm94cGxvdCcpKQpgYGAKCkMzIHBvc2l0aXZlbHkgc2tld2VkIGJ1dCBub3QgdG9vIGJhZDsgbm8gb2J2aW91cyBub24tbGluZWFyaXRpZXMKCk5vdyBjaGVjayBmb3IgY29sbGluZWFyaXR5IGFtb25nIGFsbCBwcmVkaWN0b3JzIC0gY29ycmVsYXRpb25zIGFuZCBWSUZzCgpgYGB7ciB9CmNvcihwYXJ1ZWxvWyxjKCdsYXQnLCdsb25nJywnbWFwJywnbWF0JywnamphbWFwJywnZGpmbWFwJyldKQp2aWYobG0oYzN+bGF0K2xvbmcrbWFwK21hdCtqamFtYXArZGpmbWFwLCBkYXRhPXBhcnVlbG8pKQpgYGAKCk9idmlvdXMgY29sbGluZWFyaXR5IHdpdGggZW52aXJvbm1lbnRhbCB2YXJpYWJsZXMgdGVuZGluZyB0byBiZSBjb3JyZWxhdGVkIHN0cm9uZ2x5IHdpdGggbGF0IG9yIGxvbmcsIHNvIHdlJ2xsIHNwbGl0IHByZWRpY3RvcnMgaW50byAyIGdyb3Vwcywgb25lIHdpdGggbGF0IGFuZCBsb25nCgojIyBGaXJzdCBtb2RlbCBjMyBhZ2FpbnN0IGxhdCBhbmQgbG9uZyBhbmQgbGF0XCpsb25nIGFuZCBjaGVjayBmb3IgY29sbGluZWFyaXR5CgpgYGB7ciB9CnZpZihsbShjM35sYXQrbG9uZytsYXQqbG9uZywgZGF0YT1wYXJ1ZWxvKSkKYGBgCgpWSUZzIHZlcnkgaGlnaCBpbmRpY2F0aW5nIG9idmlvdXMgY29sbGluZWFyaXR5IGFzIGV4cGVjdGVkIHdpdGggaW50ZXJhY3Rpb24gdGVybQoKIyMjIFJ1biB1bmNlbnRyZWQgbW9kZWwKCmBgYHtyIH0KcGFydWVsby5sbSA8LSBsbShjM35sYXQrbG9uZytsYXQqbG9uZywgZGF0YT1wYXJ1ZWxvKQpgYGAKCkdldCByZWdyZXNzaW9uIGRpYWdub3N0aWNzIChyZXNpZHVhbCBwbG90IGFuZCBDb29rcyBEKQoKYGBge3IgfQpwbG90KHBhcnVlbG8ubG0pCmF1Z21lbnQocGFydWVsby5sbSkKYGBgCgojIyMjIERpc3BsYXkgcmVzdWx0cyBvZiBtb2RlbCBmaXR0aW5nCgpgYGB7ciB9CmdsYW5jZShwYXJ1ZWxvLmxtKQp0aWR5KHBhcnVlbG8ubG0sIGNvbmYuaW50PVRSVUUpCmBgYAoKR2V0IHN0YW5kYXJkaXplZCByZWdyZXNzaW9uIGNvZWZmaWNpZW50cywgdXNlIGxtLmJldGEgZnVuY3Rpb24gZnJvbSBsbS5iZXRhIHBhY2thZ2UKCmBgYHtyIH0KbG0uYmV0YS5wYXJ1ZWxvIDwtIGxtLmJldGEocGFydWVsby5sbSkKdGlkeShsbS5iZXRhLnBhcnVlbG8sIGNvbmYuaW50PVRSVUUpCmBgYAoKIyMjIENlbnRyZSBwcmVkaWN0b3JzIGFuZCByZWZpdCBtb2RlbAoKYGBge3IgfQpwYXJ1ZWxvJGNsYXQgPC0gc2NhbGUocGFydWVsbyRsYXQsIGNlbnRlcj1UUlVFLCBzY2FsZT1GQUxTRSkKcGFydWVsbyRjbG9uZyA8LSBzY2FsZShwYXJ1ZWxvJGxvbmcsIGNlbnRlcj1UUlVFLCBzY2FsZT1GQUxTRSkKcGFydWVsbzEubG0gPC0gbG0oYzN+Y2xhdCtjbG9uZytjbGF0KmNsb25nLCBkYXRhPXBhcnVlbG8pCmBgYAoKUmVjaGVjayBjb2xsaW5lYXJpdHkKCmBgYHtyIH0KdmlmKGxtKGMzfmNsYXQrY2xvbmcrY2xhdCpjbG9uZywgZGF0YT1wYXJ1ZWxvKSkKYGBgCgpSZWdyZXNzaW9uIGRpYWdub3N0aWNzIChyZXNpZHVhbCBwbG90IGFuZCBDb29rcyBEKQoKYGBge3IgfQpwbG90KHBhcnVlbG8xLmxtKQphdWdtZW50KHBhcnVlbG8xLmxtKQpgYGAKCkRpYWdub3N0aWNzIGxvb2sgYmV0dGVyIG5vdwoKIyMjIyBEaXNwbGF5IHJlc3VsdHMgb2YgbW9kZWwgZml0dGluZwoKYGBge3IgfQpnbGFuY2UocGFydWVsbzEubG0pCnRpZHkocGFydWVsbzEubG0sIGNvbmYuaW50PVRSVUUpCmBgYAoKR2V0IHN0YW5kYXJkaXplZCByZWdyZXNzaW9uIGNvZWZmaWNpZW50cywgdXNlIGxtLmJldGEgZnVuY3Rpb24gZnJvbSBsbS5iZXRhIHBhY2thZ2UKCmBgYHtyIH0KbG0uYmV0YShwYXJ1ZWxvMS5sbSkKYGBgCgojIyMgU3RhbmRhcmRpc2UgcHJlZGljdG9ycyBhbmQgcmVmaXQgbW9kZWwKCmBgYHtyIH0KcGFydWVsbyRzbGF0IDwtIHNjYWxlKHBhcnVlbG8kbGF0LCBjZW50ZXI9VFJVRSwgc2NhbGU9VFJVRSkKcGFydWVsbyRzbG9uZyA8LSBzY2FsZShwYXJ1ZWxvJGxvbmcsIGNlbnRlcj1UUlVFLCBzY2FsZT1UUlVFKQpwYXJ1ZWxvMi5sbSA8LSBsbShjM35zbGF0K3Nsb25nK3NsYXQqc2xvbmcsIGRhdGE9cGFydWVsbykKYGBgCgpSZWNoZWNrIGNvbGxpbmVhcml0eQoKYGBge3IgfQp2aWYobG0oYzN+c2xhdCtzbG9uZytzbGF0KnNsb25nLCBkYXRhPXBhcnVlbG8pKQpgYGAKClJlZ3Jlc3Npb24gZGlhZ25vc3RpY3MgKHJlc2lkdWFsIHBsb3QgYW5kIENvb2tzIEQpCgpgYGB7ciB9CnBsb3QocGFydWVsbzIubG0pCmF1Z21lbnQocGFydWVsbzIubG0pCmBgYAoKIyMjIyBEaXNwbGF5IHJlc3VsdHMgb2YgbW9kZWwgZml0dGluZwoKYGBge3IgfQpnbGFuY2UocGFydWVsbzIubG0pCnRpZHkocGFydWVsbzIubG0sIGNvbmYuaW50PVRSVUUpCmBgYAoKR2V0IHN0YW5kYXJkaXNlZCByZWdyZXNzaW9uIGNvZWZmaWNpZW50cywgdXNlIGxtLmJldGEgZnVuY3Rpb24gZnJvbSBsbS5iZXRhIHBhY2thZ2UKCmBgYHtyIH0KbG0uYmV0YShwYXJ1ZWxvMi5sbSkKYGBgCgojIyMgM2Qgc2NhdHRlcnBsb3Qgd2l0aCBzbW9vdGhpbmcgc3VyZmFjZQoKKipOb3RlIG9uIG1hYyBPUyAtIG5lZWQgeHF1YXJ0eiBpbnN0YWxsZWQuKiogR3JhcGhpYyBvcGVucyBpbiBzZXBhcmF0ZSB3aW5kb3cgaW4gTWFjL1hxdWFydHo7IGhhdmVuJ3QgY2hlY2tlZCBvbiBvdGhlciBvcGVyYXRpbmcgc3lzdGVtcy4KClJvdGF0ZSB0aGUgZ3JhcGggdXNpbmcgdGhlIG1vdXNlIG9yIGN1cnNvciBrZXlzCgpgYGB7ciBlcnJvcj1UUlVFfQpzY2F0dGVyM2QoYzN+bGF0K2xvbmcsIGdyaWQgPSBGQUxTRSwgZml0ID0gInNtb290aCIsIGRhdGE9cGFydWVsbykKYGBgCgojIyMgRXhhbWluZSBzaW1wbGUgc2xvcGVzIHVzaW5nIHJlZ2hlbHBlciBwYWNrYWdlCgpgYGB7ciB9CnNpbXBsZV9zbG9wZXMocGFydWVsby5sbSkKYGBgCg==