> # test.full.R: test earth
> 
> print(R.version.string)
[1] "R version 4.4.1 (2024-06-14 ucrt)"
> 
> source("test.prolog.R")
> source("check.models.equal.R")
> library(earth)
Loading required package: Formula
Loading required package: plotmo
Loading required package: plotrix
> library(mda)
Loading required package: class
Loaded mda 0.5-4

> data(ozone1)
> data(trees)
> data(etitanic)
> 
> PRINT.TIME <- FALSE         # FALSE for no time results (for diff against reference)
> PLOT <- TRUE                # TRUE to do plots too, FALSE for speed
> options.old <- options()
> options(warn=1) # print warnings as they occur
> # options(digits=5) # removed because want to check against default
> 
> printh <- function(x, expect.warning=FALSE, max.print=0) # like print but with a header
+ {
+     cat("===", deparse(substitute(x)), " ", sep="")
+     if(expect.warning)
+         cat(" expect warning -->")
+     else if (NROW(x) > 1)
+         cat("\n")
+     if (max.print > 0)
+         print(head(x, n=max.print))
+     else
+         print(x)
+ }
> 
> print(citation("earth"))
To cite package 'earth' in publications use:

  Milborrow S, Hastie T, Tibshirani R (2011). _earth: Multivariate
  Adaptive Regression Splines_. R package version 5.3.4,
  <https://CRAN.R-project.org/package=earth>.

A BibTeX entry for LaTeX users is

  @Manual{,
    title = {earth: Multivariate Adaptive Regression Splines},
    author = {Stephen Milborrow and Trevor Hastie and Rob Tibshirani},
    year = {2011},
    note = {R package version 5.3.4},
    url = {https://CRAN.R-project.org/package=earth},
  }
> 
> #--- test examples from man pages ------------------------------------------------------------
> 
> cat("--- earth.Rd -----------------------------\n")
--- earth.Rd -----------------------------
> example(earth)

earth> earth.mod <- earth(Volume ~ ., data = trees)

earth> plotmo(earth.mod)
 plotmo grid:    Girth Height
                  12.9     76

earth> summary(earth.mod, digits = 2, style = "pmax")
Call: earth(formula=Volume~., data=trees)

Volume =
  29
  -  3.4 * pmax(0,     14 -  Girth) 
  +  6.2 * pmax(0,  Girth -     14) 
  + 0.58 * pmax(0, Height -     75) 

Selected 4 of 5 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 5 terms
Importance: Girth, Height
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 11    RSS 209    GRSq 0.96    RSq 0.97
> 
> set.seed(2015)
> 
>     train.subset <- sample(1:nrow(trees), .8 * nrow(trees))
>     test.subset <- (1:nrow(trees))[-train.subset]
> 
>     earth.model <- earth(Volume ~ ., data = trees[train.subset,])
> 
>     # print R-Squared on the test data
>     print(summary(earth.model, newdata=trees[test.subset,]))
RSq 0.959 on newdata (7 cases)
> 
>     # manually calculate R-Squared on the test data (same as above call to summary)
>     yhat <- predict(earth.model, newdata = trees[test.subset,])
>     y <- trees$Volume[test.subset]
>     printh(1 - sum((y - yhat)^2) / sum((y - mean(y))^2)) # print R-Squared
===1 - sum((y - yhat)^2)/sum((y - mean(y))^2) [1] 0.9592516
> 
> newrsq <- 1 - sum((y - yhat)^2) / sum((y - mean(y))^2)
> stopifnot(abs(summary(earth.model, newdata=trees[test.subset,])$newrsq - newrsq) < 1e-10)
> 
> cars <- earth(mpg ~ ., data = mtcars, pmethod = "none", trace = 4)
Call: earth(formula=mpg~., data=mtcars, pmethod="none", trace=4)

x[32,10]:
              cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4       6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710      4  108  93 3.85 2.320 18.61  1  1    4    1
...             6  258 110 3.08 3.215 19.44  1  0    3    1
Volvo 142E      4  121 109 4.11 2.780 18.60  1  1    4    2

y[32,1]:
     mpg
1   21.0
2   21.0
3   22.8
... 21.4
32  21.4

Forward pass: minspan 5 endspan 10   x[32,10] 2.5 kB   bx[32,21] 5.25 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.8157 0.8602       0.8602    2         disp         145  2   3         1 
4      0.7815 0.8797      0.01956    3           hp         123  4   5         1 
6      0.7601 0.9099      0.03016    6         qsec       18.52  6   7         1 
8      0.6839 0.9260      0.01611    4         drat        3.15  8   9         1 
10     0.5031 0.9374      0.01144    9         gear           4  10  11        1 
12     0.3575 0.9458     0.008417    2         disp       275.8  12            1 
14     0.0073 0.9494     0.003535    6         qsec       17.02  13            1 
16    -0.5893 0.9587     0.009271    7           vs           0< 14            1 
18   -35.8726 0.9616     0.002977   10         carb           2  15  16        1 reject (negative GRSq)

Reached minimum GRSq -10 at 17 terms, 14 terms used (GRSq -36)
After forward pass GRSq -35.873 RSq 0.962
Forward pass complete: 17 terms, 14 terms used

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2      0.6706  0.7118     0.6706      1  1 3
          3      0.8157  0.8602     0.1450      1  1 2 3
          4      0.7988  0.8691    -0.0169      2  1 2 3 4
          5      0.7815  0.8797    -0.0173      2  1 2 3 4 5
          6      0.7601  0.8899    -0.0214      4  1 3 4 6 13 14
          7      0.7934  0.9224     0.0332      4  1 3 4 5 6 13 14
          8      0.7852  0.9354    -0.0082      5  1 3 4 5 6 9 13 14
          9      0.7579  0.9433    -0.0272      5  1 3 4 5 6 9 12 13 14
         10      0.6997  0.9472    -0.0582      6  1 3 4 5 6 9 10 12 13 14
         11      0.6132  0.9513    -0.0865      6  1 2 3 4 5 6 9 10 12 13 14
         12      0.4534  0.9539    -0.1598      6  1 2 3 4 5 6 9 10 11 12 13 14
         13      0.1741  0.9579    -0.2793      6  1 2 3 4 5 6 8 9 10 11 12 13 14
chosen   14     -0.5893  0.9587    -0.7634      6  1 2 3 4 5 6 7 8 9 10 11 12 13 14

Prune none penalty 2 nprune null: selected 14 of 14 terms, and 6 of 10 preds
After pruning pass GRSq -0.589 RSq 0.959
> 
> stopifnot(max(coef(cars) - cars$coefficients) == 0)
> stopifnot(max(coef(cars, type="response") - cars$coefficients) == 0)
> stopifnot(max(coef(cars, type="earth") - cars$coefficients) == 0)
> expect.err(try(coef(cars, type="nonesuch")), "type=\"nonesuch\" is not allowed")
Error : type="nonesuch" is not allowed
Choose one of: "response" "earth" "glm"
Got expected error from try(coef(cars, type = "nonesuch"))
> expect.err(try(coef(cars, type="glm")), "type == \"glm\" is not allowed because this is not an earth-glm model")
Error : coef.earth: type == "glm" is not allowed because this is not an earth-glm model
Got expected error from try(coef(cars, type = "glm"))
> expect.err(try(coefficients(cars, type="glm")), "type == \"glm\" is not allowed because this is not an earth-glm model")
Error : coef.earth: type == "glm" is not allowed because this is not an earth-glm model
Got expected error from try(coefficients(cars, type = "glm"))
> stopifnot(isTRUE(all.equal(coef(cars), coefficients(cars))))
> stopifnot(isTRUE(all.equal(coef(cars, type="earth"), coefficients(cars, type="earth"))))
> stopifnot(identical(names(coef(cars)), rownames(cars$coefficients)))
> 
> get.used.pred.names <- function(obj) # obj is an earth object
+ {
+   any1 <- function(x) any(x != 0)    # like any but no warning if x is double
+   names(which(apply(obj$dirs[obj$selected.terms,,drop=FALSE],2,any1)))
+ }
> printh(get.used.pred.names(cars))
===get.used.pred.names(cars) 
[1] "disp" "hp"   "drat" "qsec" "vs"   "gear"
> 
> a1 <- earth(survived ~ ., data=etitanic,   # c.f. Harrell "Reg. Mod. Strat." ch. 12
+              degree=2, trace=1,
+              glm=list(family=binomial))
x[1046,6] with colnames pclass2nd pclass3rd sexmale age sibsp parch
y[1046,1] with colname survived, and values 1, 1, 0, 0, 0, 1, 1, 0, 1, 0,...
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
Reached nk 21
After forward pass GRSq 0.406 RSq 0.450
Prune backward penalty 3 nprune null: selected 8 of 17 terms, and 5 of 6 preds
After pruning pass GRSq 0.42 RSq 0.439
GLM survived devratio 0.37 dof 1038/1045 iters 5
> printh(a1)
===a1 
GLM (family binomial, link logit):
 nulldev   df       dev   df   devratio     AIC iters converged
 1414.62 1045   892.794 1038      0.369   908.8     5         1

Earth selected 8 of 17 terms, and 5 of 6 predictors
Termination condition: Reached nk 21
Importance: sexmale, pclass3rd, pclass2nd, age, sibsp, parch-unused
Number of terms at each degree of interaction: 1 3 4
Earth GCV 0.1404529    RSS 141.7629    GRSq 0.4197106    RSq 0.4389834
> 
> a1a <- earth(etitanic[,-2], etitanic[,2],  # equivalent but using earth.default
+              degree=2, trace=1,
+              glm=list(family=binomial))
x[1046,6] with colnames pclass2nd pclass3rd sexmale age sibsp parch
y[1046,1] with colname `etitanic[, 2]`, and values 1, 1, 0, 0, 0, 1, 1, 0, 1, 0,...
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
Reached nk 21
After forward pass GRSq 0.406 RSq 0.450
Prune backward penalty 3 nprune null: selected 8 of 17 terms, and 5 of 6 preds
After pruning pass GRSq 0.42 RSq 0.439
GLM `etitanic[, 2]` devratio 0.37 dof 1038/1045 iters 5
> printh(a1a)
===a1a 
GLM (family binomial, link logit):
 nulldev   df       dev   df   devratio     AIC iters converged
 1414.62 1045   892.794 1038      0.369   908.8     5         1

Earth selected 8 of 17 terms, and 5 of 6 predictors
Termination condition: Reached nk 21
Importance: sexmale, pclass3rd, pclass2nd, age, sibsp, parch-unused
Number of terms at each degree of interaction: 1 3 4
Earth GCV 0.1404529    RSS 141.7629    GRSq 0.4197106    RSq 0.4389834
> plotmo(a1a)
 plotmo grid:    pclass  sex age sibsp parch
                    3rd male  28     0     0
> 
> a1b <- earth(etitanic[,-2,drop=FALSE], etitanic[,2,drop=FALSE],
+              degree=2, trace=1,
+              glm=list(family=binomial))
x[1046,6] with colnames pclass2nd pclass3rd sexmale age sibsp parch
y[1046,1] with colname survived, and values 1, 1, 0, 0, 0, 1, 1, 0, 1, 0,...
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
Reached nk 21
After forward pass GRSq 0.406 RSq 0.450
Prune backward penalty 3 nprune null: selected 8 of 17 terms, and 5 of 6 preds
After pruning pass GRSq 0.42 RSq 0.439
GLM survived devratio 0.37 dof 1038/1045 iters 5
> printh(a1b)
===a1b 
GLM (family binomial, link logit):
 nulldev   df       dev   df   devratio     AIC iters converged
 1414.62 1045   892.794 1038      0.369   908.8     5         1

Earth selected 8 of 17 terms, and 5 of 6 predictors
Termination condition: Reached nk 21
Importance: sexmale, pclass3rd, pclass2nd, age, sibsp, parch-unused
Number of terms at each degree of interaction: 1 3 4
Earth GCV 0.1404529    RSS 141.7629    GRSq 0.4197106    RSq 0.4389834
> plotmo(a1b)
 plotmo grid:    pclass  sex age sibsp parch
                    3rd male  28     0     0
> 
> # test modvars for the example in the man page earth.object.Rd
> 
> aform <- earth(survived ~ age + pclass + sqrt(age) - sex, data=etitanic)
> cat("\nattr(aform$terms, \"factors\")\n")

attr(aform$terms, "factors")
> print(attr(aform$terms, "factors"))
          age pclass sqrt(age)
survived    0      0         0
age         1      0         0
pclass      0      1         0
sqrt(age)   0      0         1
sex         0      0         0
> cat("\na$modvars\n")

a$modvars
> print(aform$modvars)
       age pclass2nd pclass3rd sqrt(age)
age      1         0         0         1
pclass   0         1         1         0
> cat("\n")

> 
> axy.dat <- data.frame(age=etitanic$age, pclass=etitanic$pclass, sqrt_age=sqrt(etitanic$age))
> axy <- earth(axy.dat, etitanic$survived)
> cat("\nattr(axy$terms, \"factors\")\n")

attr(axy$terms, "factors")
> print(attr(axy$terms, "factors"))
NULL
> cat("\na$modvars\n")

a$modvars
> print(axy$modvars)
         age pclass2nd pclass3rd sqrt_age
age        1         0         0        0
pclass     0         1         1        0
sqrt_age   0         0         0        1
> cat("\n")

> 
> # x and y dataframes but with missing column names
> xdf_nonames <- etitanic[,-2,drop=FALSE]
> cat("original colnames of xdf_nonames:", paste(colnames(xdf_nonames)), "\n")
original colnames of xdf_nonames: pclass sex age sibsp parch 
> ydf_nonames <- etitanic[,2,drop=FALSE]
> colnames(xdf_nonames) <- NULL # weird for a dataframe, but earth still works
> colnames(ydf_nonames) <- NULL
> earth_df_nonames <- earth(xdf_nonames, ydf_nonames,
+              degree=2, trace=1,
+              glm=list(family=binomial))
x[1046,6] with colnames xdf_nonames12nd xdf_nonames13rd xdf_nonames2male xdf_nona...
y[1046,1] with colname ydf_nonames, and values 1, 1, 0, 0, 0, 1, 1, 0, 1, 0,...
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
Reached nk 21
After forward pass GRSq 0.406 RSq 0.450
Prune backward penalty 3 nprune null: selected 8 of 17 terms, and 5 of 6 preds
After pruning pass GRSq 0.42 RSq 0.439
GLM ydf_nonames devratio 0.37 dof 1038/1045 iters 5
> cat("earth_df_nonames:\n")
earth_df_nonames:
> print(summary(earth_df_nonames))
Call: earth(x=xdf_nonames, y=ydf_nonames, trace=1, glm=list(family=binomial),
            degree=2)

GLM coefficients
                                      ydf_nonames
(Intercept)                             2.9135260
xdf_nonames13rd                        -5.0300560
xdf_nonames2male                       -3.1856245
h(xdf_nonames3-32)                     -0.0375715
xdf_nonames12nd * xdf_nonames2male     -1.7680945
xdf_nonames13rd * xdf_nonames2male      1.2226954
xdf_nonames13rd * h(4-xdf_nonames4)     0.6186527
xdf_nonames2male * h(16-xdf_nonames3)   0.2418140

GLM (family binomial, link logit):
 nulldev   df       dev   df   devratio     AIC iters converged
 1414.62 1045   892.794 1038      0.369   908.8     5         1

Earth selected 8 of 17 terms, and 5 of 6 predictors
Termination condition: Reached nk 21
Importance: xdf_nonames2male, xdf_nonames13rd, xdf_nonames12nd, ...
Number of terms at each degree of interaction: 1 3 4
Earth GCV 0.1404529    RSS 141.7629    GRSq 0.4197106    RSq 0.4389834
> cat("\nearth_df_nonames$modvars\n")

earth_df_nonames$modvars
> print(earth_df_nonames$modvars)
             xdf_nonames12nd xdf_nonames13rd xdf_nonames2male xdf_nonames3
xdf_nonames1               1               1                0            0
xdf_nonames2               0               0                1            0
xdf_nonames3               0               0                0            1
xdf_nonames4               0               0                0            0
xdf_nonames5               0               0                0            0
             xdf_nonames4 xdf_nonames5
xdf_nonames1            0            0
xdf_nonames2            0            0
xdf_nonames3            0            0
xdf_nonames4            1            0
xdf_nonames5            0            1
> options(warn=2)
> expect.err(try(plotmo(earth_df_nonames)), "Cannot determine which variables to plot")
Error : (converted from warning) Cannot determine which variables to plot (use all1=TRUE?)
             single.names=c(xdf_nonames2,xdf_nonames1,xdf_nonames3)
             colnames(x)=c(x1,x2,x3,x4,x5)

Got expected error from try(plotmo(earth_df_nonames))
> plotmo(earth_df_nonames, all1=TRUE, SHOWCALL=TRUE)
 plotmo grid:    x1   x2 x3 x4 x5
                3rd male 28  0  0
> options(warn=1)
> plotmo(earth_df_nonames, trace=1, SHOWCALL=TRUE)
stats::predict(earth.object, NULL, type="response")
stats::fitted(object=earth.object)
got model response from getCall(object)$y
Warning: Cannot determine which variables to plot (use all1=TRUE?)
             single.names=c(xdf_nonames2,xdf_nonames1,xdf_nonames3)
             colnames(x)=c(x1,x2,x3,x4,x5)


 plotmo grid:    x1   x2 x3 x4 x5
                3rd male 28  0  0

> 
> # xmat in canonical form (double matrix) but with missing column names
> xmat_nonames <- etitanic[,"age",drop=FALSE]
> xmat_nonames$pclass <- as.numeric(etitanic[,"pclass"])
> xmat_nonames <- as.matrix(xmat_nonames)
> cat("original colnames of xmat_nonames:", paste(colnames(xmat_nonames)), "\n")
original colnames of xmat_nonames: age pclass 
> ymat_nonames <- as.numeric(etitanic[,"survived"])
> ymat_nonames <- as.matrix(ymat_nonames)
> colnames(xmat_nonames) <- NULL
> colnames(ymat_nonames) <- NULL
> earth_mat_nonames <- earth(xmat_nonames, ymat_nonames, degree=2, trace=1)
x[1046,2] with colnames xmat_nonames1 xmat_nonames2
y[1046,1] with colname ymat_nonames, and values 1, 1, 0, 0, 0, 1, 1, 0, 1, 0,...
Forward pass term 1, 2, 4, 6, 8, 10
RSq changed by less than 0.001 at 9 terms (DeltaRSq 0.00055)
After forward pass GRSq 0.120 RSq 0.162
Prune backward penalty 3 nprune null: selected 6 of 9 terms, and 2 of 2 preds
After pruning pass GRSq 0.137 RSq 0.158
> cat("earth_mat_nonames:\n")
earth_mat_nonames:
> print(summary(earth_mat_nonames))
Call: earth(x=xmat_nonames, y=ymat_nonames, trace=1, degree=2)

                                         coefficients
(Intercept)                                0.47789359
h(18-xmat_nonames1)                        0.03051719
h(xmat_nonames1-18)                       -0.00609975
h(2-xmat_nonames2)                         0.28092736
h(xmat_nonames2-2)                        -0.16376873
h(23-xmat_nonames1) * h(xmat_nonames2-2)  -0.01570789

Selected 6 of 9 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 9 terms
Importance: xmat_nonames2, xmat_nonames1
Number of terms at each degree of interaction: 1 4 1
GCV 0.2088003    RSS 212.8039    GRSq 0.1373292    RSq 0.1578438
> options(warn=2)
> expect.err(try(plotmo(earth_mat_nonames)), "Cannot determine which variables to plot")
Error : (converted from warning) Cannot determine which variables to plot (use all1=TRUE?)
             single.names=c(xmat_nonames2,xmat_nonames2,xmat_nonames1,xmat_nonames1)
             colnames(x)=c(x1,x2)

Got expected error from try(plotmo(earth_mat_nonames))
> options(warn=1)
> plotmo(earth_mat_nonames)
Warning: Cannot determine which variables to plot (use all1=TRUE?)
             single.names=c(xmat_nonames2,xmat_nonames2,xmat_nonames1,xmat_nonames1)
             colnames(x)=c(x1,x2)

 plotmo grid:    x1 x2
                 28  2
> 
> # xmat in canonical form (double matrix) but with some missing column names
> xmat_partial <- etitanic[,"age",drop=FALSE]
> xmat_partial$pclass <- as.numeric(etitanic[,"pclass"])
> xmat_partial$sibsp <- as.numeric(etitanic[,"sibsp"])
> xmat_partial <- as.matrix(xmat_partial)
> cat("original colnames of xmat_partial:", paste(colnames(xmat_partial)), "\n")
original colnames of xmat_partial: age pclass sibsp 
> colnames(xmat_partial) <- c("", "x2", "") # some column names are missing (earth will create them)
> ymat_partial <- as.numeric(etitanic[,"survived"])
> ymat_partial <- as.matrix(ymat_partial)
> colnames(ymat_partial) <- "yy"
> earth_mat_partialnames <- earth(xmat_partial, ymat_partial, degree=2, trace=1)
x[1046,3] with colnames xmat_partial1 x2 xmat_partial3
y[1046,1] with colname yy, and values 1, 1, 0, 0, 0, 1, 1, 0, 1, 0,...
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
RSq changed by less than 0.001 at 19 terms, 17 terms used (DeltaRSq 0.0009)
After forward pass GRSq 0.126 RSq 0.195
Prune backward penalty 3 nprune null: selected 7 of 17 terms, and 3 of 3 preds
After pruning pass GRSq 0.157 RSq 0.181
> cat("earth_mat_partialnames:\n")
earth_mat_partialnames:
> print(summary(earth_mat_partialnames))
Call: earth(x=xmat_partial, y=ymat_partial, trace=1, degree=2)

                                         coefficients
(Intercept)                                0.93106453
h(xmat_partial1-5)                        -0.03561187
h(xmat_partial1-18)                        0.03022469
h(2-x2)                                    0.27484540
h(x2-2)                                   -0.18280547
h(18-xmat_partial1) * h(xmat_partial3-2)  -0.04797511
h(18-xmat_partial1) * h(xmat_partial3-3)   0.04721023

Selected 7 of 17 terms, and 3 of 3 predictors
Termination condition: RSq changed by less than 0.001 at 17 terms
Importance: x2, xmat_partial1, xmat_partial3
Number of terms at each degree of interaction: 1 4 2
GCV 0.2040487    RSS 206.9554    GRSq 0.1569604    RSq 0.1809888
> options(warn=2)
> expect.err(try(plotmo(earth_mat_partialnames)), "Cannot determine which variables to plot")
Error : (converted from warning) Cannot determine which variables to plot (use all1=TRUE?)
             single.names=c(x2,x2,xmat_partial1,xmat_partial1)
             colnames(x)=c(x1,x2,x3)

Got expected error from try(plotmo(earth_mat_partialnames))
> options(warn=1)
> plotmo(earth_mat_partialnames)
Warning: Cannot determine which variables to plot (use all1=TRUE?)
             single.names=c(x2,x2,xmat_partial1,xmat_partial1)
             colnames(x)=c(x1,x2,x3)

 plotmo grid:    x1 x2 x3
                 28  2  0
> 
> # use a partial column name that will cause a duplicate within gen.colnames
> colnames(xmat_partial) <- c("", "xmat_partial1", "")
> expect.err(try(earth(xmat_partial, ymat_partial, degree=2, trace=1)),
+            "Duplicate colname in xmat_partial (colnames are \"xmat_partial1\", \"xmat_partial1\", \"xmat_partial3\")")
Error : Duplicate colname in xmat_partial (colnames are "xmat_partial1", "xmat_partial1", "xmat_partial3")
Got expected error from try(earth(xmat_partial, ymat_partial, degree = 2, trace = 1))
> 
> a2 <- earth(pclass ~ ., data=etitanic, glm=list(family=binomial), trace=1)
x[1046,5] with colnames survived sexmale age sibsp parch
y[1046,3] with colnames 1st 2nd 3rd
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14
RSq changed by less than 0.001 at 13 terms, 10 terms used (DeltaRSq 0.00065)
After forward pass GRSq 0.163 RSq 0.195
Prune backward penalty 2 nprune null: selected 8 of 10 terms, and 4 of 5 preds
After pruning pass GRSq 0.167 RSq 0.189
GLM 1st devratio 0.25 dof 1038/1045 iters 5
GLM 2nd devratio 0.02 dof 1038/1045 iters 5
GLM 3rd devratio 0.21 dof 1038/1045 iters 5
> printh(a2)
===a2 
GLM (family binomial, link logit):
    nulldev   df       dev   df   devratio     AIC iters converged
1st 1223.31 1045   920.802 1038     0.2470   936.8     5         1
2nd 1175.31 1045  1147.518 1038     0.0236  1164.0     5         1
3rd 1448.21 1045  1142.756 1038     0.2110  1159.0     5         1

Earth selected 8 of 10 terms, and 4 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 10 terms
Importance: age, survived, sibsp, parch, sexmale-unused
Number of terms at each degree of interaction: 1 7 (additive model)

Earth
          GCV      RSS         GRSq        RSq
1st 0.1483414 150.7467  0.251448718 0.27137124
2nd 0.1885520 191.6094 -0.004971341 0.02177575
3rd 0.1927692 195.8949  0.229032722 0.24955184
All 0.5296626 538.2511  0.166969402 0.18914032
> 
> ldose <- rep(0:5, 2) - 2 # Venables and Ripley 4th edition page 191
> sex <- factor(rep(c("male", "female"), times=c(6,6)))
> numdead <- c(1,4,9,13,18,20,0,2,6,10,12,16)
> pair <- cbind(numdead, numalive=20 - numdead)
> 
> a3 <- earth(pair ~ sex + ldose,
+             glm=list(family=binomial(link=probit), maxit=100), trace=1)
x[12,2] with colnames sexmale ldose
y[12,2] with colnames numdead numalive
earth and glm: unweighted
Response columns numdead and numalive are a binomial pair (240 obs in total)
yfrac[12,1] with colname numdead, and values 0.05, 0.2, 0.45, 0.65, 0.9, 1...
Forward pass term 1, 2, 4, 6
RSq changed by less than 0.001 at 5 terms, 3 terms used (DeltaRSq 0)
After forward pass GRSq 0.907 RSq 0.981
Prune backward penalty 2 nprune null: selected 3 of 3 terms, and 2 of 2 preds
After pruning pass GRSq 0.952 RSq 0.981
GLM numdead devratio 0.96 dof 9/11 iters 4
> printh(a3)
===a3 
GLM (family binomial, link probit):
 nulldev df       dev df   devratio     AIC iters converged
 124.876 11   5.56596  9      0.955   41.68     4         1

Earth selected 3 of 3 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: ldose, sexmale
Number of terms at each degree of interaction: 1 2 (additive model)
Earth GCV 0.005940233    RSS 0.02425595    GRSq 0.952486    RSq 0.9807588
> 
> numalive <- 20 - numdead
> pairmod2 <- earth(numalive + numdead ~ sex + ldose,
+                   glm=list(family=binomial()), trace=1)
Using class "Formula" because lhs of formula has terms separated by "+"
x[12,2] with colnames sexmale ldose
y[12,2] with colnames numalive numdead
earth and glm: unweighted
Response columns numalive and numdead are a binomial pair (240 obs in total)
yfrac[12,1] with colname numalive, and values 0.95, 0.8, 0.55, 0.35, 0.1, 0...
Forward pass term 1, 2, 4, 6
RSq changed by less than 0.001 at 5 terms, 3 terms used (DeltaRSq 0)
After forward pass GRSq 0.907 RSq 0.981
Prune backward penalty 2 nprune null: selected 3 of 3 terms, and 2 of 2 preds
After pruning pass GRSq 0.952 RSq 0.981
GLM numalive devratio 0.95 dof 9/11 iters 4
> printh(pairmod2)
===pairmod2 
GLM (family binomial, link logit):
 nulldev df       dev df   devratio     AIC iters converged
 124.876 11   6.75706  9      0.946   42.87     4         1

Earth selected 3 of 3 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: ldose, sexmale
Number of terms at each degree of interaction: 1 2 (additive model)
Earth GCV 0.005940233    RSS 0.02425595    GRSq 0.952486    RSq 0.9807588
> 
> # multiple responses with short (compacted) binomial data no longer supported
> numdead2.verylongname <- c(2,8,11,12,20,23,0,4,6,16,12,14) # bogus data
> doublepair <- cbind(numdead, numalive=20-numdead,
+                     numdead2.verylongname=numdead2.verylongname,
+                     numalive2.verylongname=30-numdead2.verylongname)
> expect.err(try(earth(doublepair ~ sex + ldose, trace=1, pmethod="none", glm=list(family="binomial"))),
+            "Binomial response (see above): all values should be between 0 and 1, or a binomial pair")
x[12,2] with colnames sexmale ldose
y[12,4] with colnames numdead numalive numdead2.verylongname numalive2.verylong...

print(head(y)):
     numdead numalive numdead2.verylongname numalive2.verylongname
[1,]       1       19                     2                     28
[2,]       4       16                     8                     22
[3,]       9       11                    11                     19
[4,]      13        7                    12                     18
[5,]      18        2                    20                     10
[6,]      20        0                    23                      7

Error : Binomial response (see above): all values should be between 0 and 1, or a binomial pair
Got expected error from try(earth(doublepair ~ sex + ldose, trace = 1, pmethod = "none",     glm = list(family = "binomial")))
> 
> counts <- c(18,17,15,20,10,20,25,13,12) # Dobson 1990 p. 93
> outcome <- gl(3,1,9)
> treatment <- gl(3,3)
> 
> a5 <- earth(counts ~ outcome + treatment, trace=1, pmethod="none",
+             glm=list(family=poisson))
x[9,4] with colnames outcome2 outcome3 treatment2 treatment3
y[9,1] with colname counts, and values 18, 17, 15, 20, 10, 20, 25, 1...
Forward pass term 1, 2, 4, 6
RSq changed by less than 0.001 at 5 terms, 3 terms used (DeltaRSq 0)
After forward pass GRSq -6.576 RSq 0.527
Prune none penalty 2 nprune null: selected 3 of 3 terms, and 2 of 4 preds
After pruning pass GRSq -0.894 RSq 0.527
GLM counts devratio 0.52 dof 6/8 iters 4
> printh(a5)
===a5 
GLM (family poisson, link log):
 nulldev df       dev df   devratio     AIC iters converged
 10.5815  8   5.12914  6      0.515   52.76     4         1

Earth selected 3 of 3 terms, and 2 of 4 predictors (pmethod="none")
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: outcome2, outcome3, treatment2-unused, treatment3-unused
Number of terms at each degree of interaction: 1 2 (additive model)
Earth GCV 46.875    RSS 83.33333    GRSq -0.8939394    RSq 0.5265152
> 
> a6 <- earth(numdead ~ sex + ldose,
+             glm=list(family=gaussian(link=identity)), trace=1)
x[12,2] with colnames sexmale ldose
y[12,1] with colname numdead, and values 1, 4, 9, 13, 18, 20, 0, 2, 6,...
Forward pass term 1, 2, 4, 6
RSq changed by less than 0.001 at 5 terms, 3 terms used (DeltaRSq 0)
After forward pass GRSq 0.907 RSq 0.981
Prune backward penalty 2 nprune null: selected 3 of 3 terms, and 2 of 2 preds
After pruning pass GRSq 0.952 RSq 0.981
GLM numdead devratio 0.98 dof 9/11 iters 2
> printh(a6$coefficients == a6$glm.coefficients)  # all TRUE
===a6$coefficients == a6$glm.coefficients 
            numdead
(Intercept)    TRUE
ldose          TRUE
sexmale        TRUE
> printh(a6)
===a6 
GLM (family gaussian, link identity):
 nulldev df       dev df   devratio     AIC iters converged
  504.25 11   9.70238  9      0.981    39.5     2         1

Earth selected 3 of 3 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: ldose, sexmale
Number of terms at each degree of interaction: 1 2 (additive model)
Earth GCV 2.376093    RSS 9.702381    GRSq 0.952486    RSq 0.9807588
> 
> remove(ldose)
> remove(sex)
> remove(numdead)
> remove(pair)
> remove(numdead2.verylongname)
> remove(doublepair)
> remove(counts)
> remove(outcome)
> remove(treatment)
> 
> printh(earth(cbind(Volume,lvol=log(Volume)) ~ ., data=trees))
===earth(cbind(Volume, lvol = log(Volume)) ~ ., data = trees) 
Selected 4 of 5 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 5 terms
Importance: Girth, Height
Number of terms at each degree of interaction: 1 3 (additive model)

              GCV        RSS      GRSq       RSq
Volume 11.2543915 209.113855 0.9596919 0.9742028
lvol    0.0158825   0.295106 0.9445035 0.9644822
All    11.2702739 209.408961 0.9596764 0.9741929
> attach(trees)
> printh(earth(data.frame(Girth,Height), data.frame(Volume,lvol=log(Volume))))
===earth(data.frame(Girth, Height), data.frame(Volume, lvol = log(Volume))) 
Selected 4 of 5 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 5 terms
Importance: Girth, Height
Number of terms at each degree of interaction: 1 3 (additive model)

              GCV        RSS      GRSq       RSq
Volume 11.2543915 209.113855 0.9596919 0.9742028
lvol    0.0158825   0.295106 0.9445035 0.9644822
All    11.2702739 209.408961 0.9596764 0.9741929
> detach(trees)
> 
> lm.fit <- lm(O3 ~ log(temp) + humidity*temp, data=ozone1)
> printh(lm.fit)
===lm.fit 

Call:
lm(formula = O3 ~ log(temp) + humidity * temp, data = ozone1)

Coefficients:
  (Intercept)      log(temp)       humidity           temp  humidity:temp  
     94.85623      -31.27411       -0.20050        0.63299        0.00475  

> plotmo(lm.fit, level=.95, trace=-1)
> lm.fit2 <- lm(O3 ~ temp+ibh+doy, data=ozone1)
> printh(lm.fit2)
===lm.fit2 

Call:
lm(formula = O3 ~ temp + ibh + doy, data = ozone1)

Coefficients:
(Intercept)         temp          ibh          doy  
 -7.6740829    0.3785184   -0.0009858   -0.0066324  

> plotmo(lm.fit2, all2=TRUE, clip=FALSE, trace=-1)
> 
> cat("--- print.default of earth object---------\n")
--- print.default of earth object---------
> print.default(cars, digits=3)
$rss
[1] 46.6

$rsq
[1] 0.959

$gcv
[1] 59.6

$grsq
[1] -0.589

$bx
      (Intercept) h(disp-145) h(145-disp) h(hp-123) h(123-hp) h(qsec-18.52)
 [1,]           1        15.0         0.0         0        13          0.00
 [2,]           1        15.0         0.0         0        13          0.00
 [3,]           1         0.0        37.0         0        30          0.09
 [4,]           1       113.0         0.0         0        13          0.92
 [5,]           1       215.0         0.0        52         0          0.00
 [6,]           1        80.0         0.0         0        18          1.70
 [7,]           1       215.0         0.0       122         0          0.00
 [8,]           1         1.7         0.0         0        61          1.48
 [9,]           1         0.0         4.2         0        28          4.38
[10,]           1        22.6         0.0         0         0          0.00
[11,]           1        22.6         0.0         0         0          0.38
[12,]           1       130.8         0.0        57         0          0.00
[13,]           1       130.8         0.0        57         0          0.00
[14,]           1       130.8         0.0        57         0          0.00
[15,]           1       327.0         0.0        82         0          0.00
[16,]           1       315.0         0.0        92         0          0.00
[17,]           1       295.0         0.0       107         0          0.00
[18,]           1         0.0        66.3         0        57          0.95
[19,]           1         0.0        69.3         0        71          0.00
[20,]           1         0.0        73.9         0        58          1.38
[21,]           1         0.0        24.9         0        26          1.49
[22,]           1       173.0         0.0        27         0          0.00
[23,]           1       159.0         0.0        27         0          0.00
[24,]           1       205.0         0.0       122         0          0.00
[25,]           1       255.0         0.0        52         0          0.00
[26,]           1         0.0        66.0         0        57          0.38
[27,]           1         0.0        24.7         0        32          0.00
[28,]           1         0.0        49.9         0        10          0.00
[29,]           1       206.0         0.0       141         0          0.00
[30,]           1         0.0         0.0        52         0          0.00
[31,]           1       156.0         0.0       212         0          0.00
[32,]           1         0.0        24.0         0        14          0.08
      h(18.52-qsec) h(drat-3.15) h(3.15-drat) h(gear-4) h(4-gear) h(disp-275.8)
 [1,]          2.06         0.75         0.00         0         0           0.0
 [2,]          1.50         0.75         0.00         0         0           0.0
 [3,]          0.00         0.70         0.00         0         0           0.0
 [4,]          0.00         0.00         0.07         0         1           0.0
 [5,]          1.50         0.00         0.00         0         1          84.2
 [6,]          0.00         0.00         0.39         0         1           0.0
 [7,]          2.68         0.06         0.00         0         1          84.2
 [8,]          0.00         0.54         0.00         0         0           0.0
 [9,]          0.00         0.77         0.00         0         0           0.0
[10,]          0.22         0.77         0.00         0         0           0.0
[11,]          0.00         0.77         0.00         0         0           0.0
[12,]          1.12         0.00         0.08         0         1           0.0
[13,]          0.92         0.00         0.08         0         1           0.0
[14,]          0.52         0.00         0.08         0         1           0.0
[15,]          0.54         0.00         0.22         0         1         196.2
[16,]          0.70         0.00         0.15         0         1         184.2
[17,]          1.10         0.08         0.00         0         1         164.2
[18,]          0.00         0.93         0.00         0         0           0.0
[19,]          0.00         1.78         0.00         0         0           0.0
[20,]          0.00         1.07         0.00         0         0           0.0
[21,]          0.00         0.55         0.00         0         1           0.0
[22,]          1.65         0.00         0.39         0         1          42.2
[23,]          1.22         0.00         0.00         0         1          28.2
[24,]          3.11         0.58         0.00         0         1          74.2
[25,]          1.47         0.00         0.07         0         1         124.2
[26,]          0.00         0.93         0.00         0         0           0.0
[27,]          1.82         1.28         0.00         1         0           0.0
[28,]          1.62         0.62         0.00         1         0           0.0
[29,]          4.02         1.07         0.00         1         0          75.2
[30,]          3.02         0.47         0.00         1         0           0.0
[31,]          3.92         0.39         0.00         1         0          25.2
[32,]          0.00         0.96         0.00         0         0           0.0
      h(qsec-17.02) vs
 [1,]          0.00  0
 [2,]          0.00  0
 [3,]          1.59  1
 [4,]          2.42  1
 [5,]          0.00  0
 [6,]          3.20  1
 [7,]          0.00  0
 [8,]          2.98  1
 [9,]          5.88  1
[10,]          1.28  1
[11,]          1.88  1
[12,]          0.38  0
[13,]          0.58  0
[14,]          0.98  0
[15,]          0.96  0
[16,]          0.80  0
[17,]          0.40  0
[18,]          2.45  1
[19,]          1.50  1
[20,]          2.88  1
[21,]          2.99  1
[22,]          0.00  0
[23,]          0.28  0
[24,]          0.00  0
[25,]          0.03  0
[26,]          1.88  1
[27,]          0.00  0
[28,]          0.00  1
[29,]          0.00  0
[30,]          0.00  0
[31,]          0.00  0
[32,]          1.58  1

$dirs
              cyl disp hp drat wt qsec vs am gear carb
(Intercept)     0    0  0    0  0    0  0  0    0    0
h(disp-145)     0    1  0    0  0    0  0  0    0    0
h(145-disp)     0   -1  0    0  0    0  0  0    0    0
h(hp-123)       0    0  1    0  0    0  0  0    0    0
h(123-hp)       0    0 -1    0  0    0  0  0    0    0
h(qsec-18.52)   0    0  0    0  0    1  0  0    0    0
h(18.52-qsec)   0    0  0    0  0   -1  0  0    0    0
h(drat-3.15)    0    0  0    1  0    0  0  0    0    0
h(3.15-drat)    0    0  0   -1  0    0  0  0    0    0
h(gear-4)       0    0  0    0  0    0  0  0    1    0
h(4-gear)       0    0  0    0  0    0  0  0   -1    0
h(disp-275.8)   0    1  0    0  0    0  0  0    0    0
h(qsec-17.02)   0    0  0    0  0    1  0  0    0    0
vs              0    0  0    0  0    0  2  0    0    0

$cuts
              cyl disp  hp drat wt qsec vs am gear carb
(Intercept)     0    0   0 0.00  0  0.0  0  0    0    0
h(disp-145)     0  145   0 0.00  0  0.0  0  0    0    0
h(145-disp)     0  145   0 0.00  0  0.0  0  0    0    0
h(hp-123)       0    0 123 0.00  0  0.0  0  0    0    0
h(123-hp)       0    0 123 0.00  0  0.0  0  0    0    0
h(qsec-18.52)   0    0   0 0.00  0 18.5  0  0    0    0
h(18.52-qsec)   0    0   0 0.00  0 18.5  0  0    0    0
h(drat-3.15)    0    0   0 3.15  0  0.0  0  0    0    0
h(3.15-drat)    0    0   0 3.15  0  0.0  0  0    0    0
h(gear-4)       0    0   0 0.00  0  0.0  0  0    4    0
h(4-gear)       0    0   0 0.00  0  0.0  0  0    4    0
h(disp-275.8)   0  276   0 0.00  0  0.0  0  0    0    0
h(qsec-17.02)   0    0   0 0.00  0 17.0  0  0    0    0
vs              0    0   0 0.00  0  0.0  0  0    0    0

$selected.terms
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14

$prune.terms
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
 [1,]    1    0    0    0    0    0    0    0    0     0     0     0     0
 [2,]    1    3    0    0    0    0    0    0    0     0     0     0     0
 [3,]    1    2    3    0    0    0    0    0    0     0     0     0     0
 [4,]    1    2    3    4    0    0    0    0    0     0     0     0     0
 [5,]    1    2    3    4    5    0    0    0    0     0     0     0     0
 [6,]    1    3    4    6   13   14    0    0    0     0     0     0     0
 [7,]    1    3    4    5    6   13   14    0    0     0     0     0     0
 [8,]    1    3    4    5    6    9   13   14    0     0     0     0     0
 [9,]    1    3    4    5    6    9   12   13   14     0     0     0     0
[10,]    1    3    4    5    6    9   10   12   13    14     0     0     0
[11,]    1    2    3    4    5    6    9   10   12    13    14     0     0
[12,]    1    2    3    4    5    6    9   10   11    12    13    14     0
[13,]    1    2    3    4    5    6    8    9   10    11    12    13    14
[14,]    1    2    3    4    5    6    7    8    9    10    11    12    13
      [,14]
 [1,]     0
 [2,]     0
 [3,]     0
 [4,]     0
 [5,]     0
 [6,]     0
 [7,]     0
 [8,]     0
 [9,]     0
[10,]     0
[11,]     0
[12,]     0
[13,]     0
[14,]    14

$fitted.values
       mpg
 [1,] 20.4
 [2,] 20.8
 [3,] 24.4
 [4,] 20.0
 [5,] 18.1
 [6,] 17.7
 [7,] 14.7
 [8,] 24.7
 [9,] 23.8
[10,] 18.5
[11,] 18.0
[12,] 16.8
[13,] 16.1
[14,] 14.8
[15,] 10.7
[16,] 11.6
[17,] 13.8
[18,] 30.6
[19,] 30.4
[20,] 31.7
[21,] 21.8
[22,] 16.1
[23,] 18.6
[24,] 13.8
[25,] 17.0
[26,] 30.1
[27,] 26.2
[28,] 31.1
[29,] 16.0
[30,] 18.7
[31,] 14.9
[32,] 21.0

$residuals
          mpg
 [1,]  0.5985
 [2,]  0.2222
 [3,] -1.5897
 [4,]  1.4241
 [5,]  0.6074
 [6,]  0.3738
 [7,] -0.3637
 [8,] -0.2722
 [9,] -1.0463
[10,]  0.7205
[11,] -0.2200
[12,] -0.4350
[13,]  1.1530
[14,]  0.4290
[15,] -0.2985
[16,] -1.1876
[17,]  0.9460
[18,]  1.8033
[19,]  0.0178
[20,]  2.2245
[21,] -0.3183
[22,] -0.6363
[23,] -3.4341
[24,] -0.4700
[25,]  2.2104
[26,] -2.8176
[27,] -0.1547
[28,] -0.6588
[29,] -0.2107
[30,]  0.9699
[31,]  0.0543
[32,]  0.3589

$coefficients
                  mpg
(Intercept)   21.2246
h(disp-145)    0.0215
h(145-disp)    0.1101
h(hp-123)     -0.0365
h(123-hp)      0.0972
h(qsec-18.52)  4.8944
h(18.52-qsec) -0.6719
h(drat-3.15)  -1.3666
h(3.15-drat)  -8.2362
h(gear-4)      2.0743
h(4-gear)     -2.1513
h(disp-275.8) -0.0321
h(qsec-17.02) -4.1119
vs             3.2318

$rss.per.response
[1] 46.6

$rsq.per.response
[1] 0.959

$gcv.per.response
[1] 59.6

$grsq.per.response
[1] -0.589

$rss.per.subset
 [1] 1126.0  324.6  157.5  147.3  135.4  123.9   87.4   72.8   63.8   59.5
[11]   54.8   51.9   47.4   46.6

$gcv.per.subset
 [1] 37.50 12.35  6.91  7.54  8.19  8.99  7.75  8.06  9.08 11.26 14.50 20.50
[13] 30.97 59.59

$leverages
 [1] 0.385 0.343 0.196 0.494 0.209 0.549 0.297 0.792 0.877 0.340 0.322 0.232
[13] 0.241 0.371 0.456 0.323 0.337 0.261 0.572 0.347 0.615 0.550 0.280 0.469
[25] 0.217 0.259 0.640 0.775 0.672 0.615 0.724 0.238

$pmethod
[1] "none"

$nprune
NULL

$penalty
[1] 2

$nk
[1] 21

$thresh
[1] 0.001

$termcond
[1] 3

$weights
NULL

$call
earth(formula = mpg ~ ., data = mtcars, pmethod = "none", trace = 4)

$namesx
 [1] "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"

$modvars
     cyl disp hp drat wt qsec vs am gear carb
cyl    1    0  0    0  0    0  0  0    0    0
disp   0    1  0    0  0    0  0  0    0    0
hp     0    0  1    0  0    0  0  0    0    0
drat   0    0  0    1  0    0  0  0    0    0
wt     0    0  0    0  1    0  0  0    0    0
qsec   0    0  0    0  0    1  0  0    0    0
vs     0    0  0    0  0    0  1  0    0    0
am     0    0  0    0  0    0  0  1    0    0
gear   0    0  0    0  0    0  0  0    1    0
carb   0    0  0    0  0    0  0  0    0    1

$terms
mpg ~ cyl + disp + hp + drat + wt + qsec + vs + am + gear + carb
attr(,"variables")
list(mpg, cyl, disp, hp, drat, wt, qsec, vs, am, gear, carb)
attr(,"factors")
     cyl disp hp drat wt qsec vs am gear carb
mpg    0    0  0    0  0    0  0  0    0    0
cyl    1    0  0    0  0    0  0  0    0    0
disp   0    1  0    0  0    0  0  0    0    0
hp     0    0  1    0  0    0  0  0    0    0
drat   0    0  0    1  0    0  0  0    0    0
wt     0    0  0    0  1    0  0  0    0    0
qsec   0    0  0    0  0    1  0  0    0    0
vs     0    0  0    0  0    0  1  0    0    0
am     0    0  0    0  0    0  0  1    0    0
gear   0    0  0    0  0    0  0  0    1    0
carb   0    0  0    0  0    0  0  0    0    1
attr(,"term.labels")
 [1] "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"
attr(,"order")
 [1] 1 1 1 1 1 1 1 1 1 1
attr(,"intercept")
[1] 1
attr(,"response")
[1] 1
attr(,".Environment")
<environment: R_GlobalEnv>
attr(,"predvars")
list(mpg, cyl, disp, hp, drat, wt, qsec, vs, am, gear, carb)
attr(,"dataClasses")
      mpg       cyl      disp        hp      drat        wt      qsec        vs 
"numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" 
       am      gear      carb 
"numeric" "numeric" "numeric" 

$xlevels
named list()

attr(,"class")
[1] "earth"
> cat("--- done print.default of earth object----\n")
--- done print.default of earth object----
> if (PLOT)
+     plot(cars)
> library(mda)
> (a <- fda(Species~., data=iris, method=earth, keepxy=TRUE))
Call:
fda(formula = Species ~ ., data = iris, method = earth, keepxy = TRUE)

Dimension: 2 

Percent Between-Group Variance Explained:
    v1     v2 
 97.97 100.00 

Training Misclassification Error: 0.04 ( N = 150 )
> if (PLOT)
+     plot(a)
> printh(summary(a$fit))
===summary(a$fit) 
Call: earth(x=x, y=Theta, weights=weights, keepxy=TRUE)

                        Theta1     Theta2
(Intercept)          1.2060322 -0.7346235
h(Sepal.Length-5.4) -0.1373750 -0.2294201
h(3.3-Sepal.Width)   0.1830045  0.3597030
h(Petal.Length-1.9) -1.7002724 -0.1836390
h(Petal.Length-3.5)  2.0219035  0.4940619
h(Petal.Length-4.5)  0.5710668  1.2862155
h(Petal.Length-5.3) -0.7975568 -1.4507177
h(Petal.Width-1.5)   2.0119980  3.5355314
h(Petal.Width-1.8)  -1.9863032 -3.4901478

Selected 9 of 15 terms, and 4 of 4 predictors
Termination condition: Reached nk 21
Importance: Petal.Length, Petal.Width, Sepal.Width, Sepal.Length
Number of terms at each degree of interaction: 1 8 (additive model)

             GCV       RSS      GRSq       RSq
Theta1 0.0473001  5.577943 0.9533285 0.9628137
Theta2 0.1234732 14.560786 0.8781676 0.9029281
All    0.1707733 20.138729 0.9157480 0.9328709
> expect.err(try(printh(summary(a$fit, none.such1="xxx"))), "unrecognized argument") # summary.earth unrecognized argument "none.such1"
===summary(a$fit, none.such1 = "xxx") Error : summary.earth: unrecognized argument 'none.such1'
Got expected error from try(printh(summary(a$fit, none.such1 = "xxx")))
> printh(summary(a$fit, style="bf", none.such2="xxx")) # Warning: format.earth ignored unrecognized argument "none.such2"
===summary(a$fit, style = "bf", none.such2 = "xxx") Warning: format.earth ignored argument 'none.such2'

Call: earth(x=x, y=Theta, weights=weights, keepxy=TRUE)

Theta1 =
  1.206032
  -  0.137375 * bf1
  + 0.1830045 * bf2
  -  1.700272 * bf3
  +  2.021903 * bf4
  + 0.5710668 * bf5
  - 0.7975568 * bf6
  +  2.011998 * bf7
  -  1.986303 * bf8

   bf1  h(Sepal.Length-5.4)
   bf2  h(3.3-Sepal.Width)
   bf3  h(Petal.Length-1.9)
   bf4  h(Petal.Length-3.5)
   bf5  h(Petal.Length-4.5)
   bf6  h(Petal.Length-5.3)
   bf7  h(Petal.Width-1.5)
   bf8  h(Petal.Width-1.8)

Theta2 =
  -0.7346235
  - 0.2294201 * bf1
  +  0.359703 * bf2
  -  0.183639 * bf3
  + 0.4940619 * bf4
  +  1.286216 * bf5
  -  1.450718 * bf6
  +  3.535531 * bf7
  -  3.490148 * bf8

   bf1  h(Sepal.Length-5.4)
   bf2  h(3.3-Sepal.Width)
   bf3  h(Petal.Length-1.9)
   bf4  h(Petal.Length-3.5)
   bf5  h(Petal.Length-4.5)
   bf6  h(Petal.Length-5.3)
   bf7  h(Petal.Width-1.5)
   bf8  h(Petal.Width-1.8)

Selected 9 of 15 terms, and 4 of 4 predictors
Termination condition: Reached nk 21
Importance: Petal.Length, Petal.Width, Sepal.Width, Sepal.Length
Number of terms at each degree of interaction: 1 8 (additive model)

             GCV       RSS      GRSq       RSq
Theta1 0.0473001  5.577943 0.9533285 0.9628137
Theta2 0.1234732 14.560786 0.8781676 0.9029281
All    0.1707733 20.138729 0.9157480 0.9328709
> if (PLOT) {
+     plot(a$fit, col.residuals=iris$Species, nresponse=1)
+     plotmo(a$fit, nresponse=1, ylim=c(-1.5,1.5), clip=FALSE, trace=-1)
+     plotmo(a$fit, nresponse=2, ylim=c(-1.5,1.5), clip=FALSE, trace=-1)
+ }
> a <- update(a, nk=3) # not on man page
> printh(a)
===a 
Call:
fda(formula = Species ~ ., data = iris, method = earth, keepxy = TRUE, 
    nk = 3)

Dimension: 2 

Percent Between-Group Variance Explained:
    v1     v2 
 94.38 100.00 

Training Misclassification Error: 0.04 ( N = 150 )
> printh(summary(a$fit))
===summary(a$fit) 
Call: earth(x=x, y=Theta, weights=weights, keepxy=TRUE, nk=3)

                      Theta1      Theta2
(Intercept)        -1.300791 -0.74367728
h(1.2-Petal.Width)  2.601323  0.03896856
h(Petal.Width-1.2)  1.351182  2.22366217

Selected 3 of 3 terms, and 1 of 4 predictors
Termination condition: Reached nk 3
Importance: Petal.Width, Sepal.Length-unused, Sepal.Width-unused, ...
Number of terms at each degree of interaction: 1 2 (additive model)

             GCV      RSS      GRSq       RSq
Theta1 0.1190355 16.68481 0.8825464 0.8887680
Theta2 0.2430154 34.06267 0.7602140 0.7729156
All    0.3620509 50.74747 0.8213802 0.8308418
> head(etitanic) # pclass and sex are unordered factors
  pclass survived    sex     age sibsp parch
1    1st        1 female 29.0000     0     0
2    1st        1   male  0.9167     1     2
3    1st        0 female  2.0000     1     2
4    1st        0   male 30.0000     1     2
5    1st        0 female 25.0000     1     2
6    1st        1   male 48.0000     0     0
> earth(pclass ~ ., data=etitanic, trace=2)
x[1046,5] with colnames survived sexmale age sibsp parch
y[1046,3] with colnames 1st 2nd 3rd
Forward pass: minspan 6 endspan 9   x[1046,5] 40.9 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0910 0.0980      0.09797    3          age          26  2   3         1 
4      0.1525 0.1622       0.0642    1     survived           0< 4             1 
6      0.1598 0.1758      0.01368    4        sibsp           1  5   6         1 
8      0.1670 0.1891       0.0133    5        parch           2  7   8         1 
10     0.1664 0.1918     0.002617    3          age          21  9             1 
12     0.1656 0.1941     0.002331    3          age          57  10            1 
14     0.1630 0.1947    0.0006471    3          age        55.5  11            1 reject (small DeltaRSq)

RSq changed by less than 0.001 at 13 terms, 10 terms used (DeltaRSq 0.00065)
After forward pass GRSq 0.163 RSq 0.195
Forward pass complete: 13 terms, 10 terms used
Using EvalSubsetsUsingXtx (rather than leaps) because this is a multiple response model
Prune backward penalty 2 nprune null: selected 8 of 10 terms, and 4 of 5 preds
After pruning pass GRSq 0.167 RSq 0.189
Selected 8 of 10 terms, and 4 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 10 terms
Importance: age, survived, sibsp, parch, sexmale-unused
Number of terms at each degree of interaction: 1 7 (additive model)

          GCV      RSS         GRSq        RSq
1st 0.1483414 150.7467  0.251448718 0.27137124
2nd 0.1885520 191.6094 -0.004971341 0.02177575
3rd 0.1927692 195.8949  0.229032722 0.24955184
All 0.5296626 538.2511  0.166969402 0.18914032
> 
> cat("--- format.earth.Rd ----------------------\n")
--- format.earth.Rd ----------------------
> as.func <- function( # convert expression string to func
+                object, digits = 8, use.names = TRUE, ...)
+   eval(parse(text=paste(
+     "function(x)\n",
+     "{\n",
+     "if(is.vector(x))\n",
+     "  x <- matrix(x, nrow = 1, ncol = length(x))\n",
+     "with(as.data.frame(x),\n",
+     format(object, digits = digits, use.names = use.names, style = "p", ...),
+     ")\n",
+     "}\n", sep = "")))
> a <- earth(Volume ~ ., data = trees)
> my.func <- as.func(a, use.names = FALSE)
> printh(my.func(c(10,80)))     # yields 17.60359
===my.func(c(10, 80)) [1] 17.60359
> printh(predict(a, c(10,80)))  # yields 17.60359, but is slower
===predict(a, c(10, 80))        Volume
[1,] 17.60359
> example(format.earth)

frmt.r> earth.mod <- earth(Volume ~ ., data = trees)

frmt.r> cat(format(earth.mod))
  29.05995
  -  3.419806 * h(14.2-Girth)
  +  6.229514 * h(Girth-14.2)
  + 0.5813644 * h(Height-75)

frmt.r> # yields:
frmt.r> #    29.0
frmt.r> #    -  3.42 * h(14.2-Girth)
frmt.r> #    +  6.23 * h(Girth-14.2)
frmt.r> #    + 0.581 * h(Height-75)
frmt.r> 
frmt.r> cat(format(earth.mod, style="pmax"))
  29.05995
  -  3.419806 * pmax(0,   14.2 -  Girth) 
  +  6.229514 * pmax(0,  Girth -   14.2) 
  + 0.5813644 * pmax(0, Height -     75) 

frmt.r> # yields:
frmt.r> #    29.0
frmt.r> #    -  3.42 * pmax(0,   14.2 -  Girth)
frmt.r> #    +  6.23 * pmax(0,  Girth -  14.2)
frmt.r> #    + 0.581 * pmax(0, Height -  75)
frmt.r> 
frmt.r> cat(format(earth.mod, style="C"))
29.05995
  -  3.419806 * max(0, 14.2 - x[0]) 
  +  6.229514 * max(0, x[0] - 14.2) 
  + 0.5813644 * max(0, x[1] -   75) 

frmt.r> # yields (note zero based indexing):
frmt.r> #    29.0
frmt.r> #    -  3.42 * max(0, 14.2 - x[0])
frmt.r> #    +  6.23 * max(0, x[0] - 14.2)
frmt.r> #    + 0.581 * max(0, x[1] - 75)
frmt.r> 
frmt.r> cat(format(earth.mod, style="bf"))
  29.05995
  -  3.419806 * bf1
  +  6.229514 * bf2
  + 0.5813644 * bf3

   bf1  h(14.2-Girth)
   bf2  h(Girth-14.2)
   bf3  h(Height-75)

frmt.r> # yields:
frmt.r> #    29.0
frmt.r> #    -  3.42 * bf1
frmt.r> #    +  6.23 * bf2
frmt.r> #    + 0.581 * bf3
frmt.r> #
frmt.r> #     bf1  h(14.2-Girth)
frmt.r> #     bf2  h(Girth-14.2)
frmt.r> #     bf3  h(Height-75)
frmt.r> 
frmt.r> 
frmt.r> 
> a <- earth(Volume ~ ., data = trees, degree=2)
> cat(format(a)) # basic tests of format.earth
  29.25859
  -  3.437775 * h(14.2-Girth)
  +  5.762954 * h(Girth-14.2)
  + 0.0444337 * Girth*h(Height-75)
> cat(format(a, digits=4))
  29.26
  -   3.438 * h(14.2-Girth)
  +   5.763 * h(Girth-14.2)
  + 0.04443 * Girth*h(Height-75)
> # cat(format(a, use.names=FALSE))
> cat(format(a, style="pmax"))
  29.25859
  -  3.437775 * pmax(0,   14.2 -  Girth) 
  +  5.762954 * pmax(0,  Girth -   14.2) 
  + 0.0444337 * Girth                    * pmax(0, Height -     75) 
> cat(format(a, style="max"))
  29.25859
  -  3.437775 * max(0,   14.2 -  Girth) 
  +  5.762954 * max(0,  Girth -   14.2) 
  + 0.0444337 * Girth                    * max(0, Height -     75) 
> cat(format(a, style="bf"))
  29.25859
  -  3.437775 * bf1
  +  5.762954 * bf2
  + 0.0444337 * bf3 * bf4

   bf1  h(14.2-Girth)
   bf2  h(Girth-14.2)
   bf3  Girth
   bf4  h(Height-75)
> cat(format(a, use.names=FALSE, style="p"))
  29.25859
  -  3.437775 * pmax(0,  14.2 - x[,1]) 
  +  5.762954 * pmax(0, x[,1] -  14.2) 
  + 0.0444337 * x[,1]                  * pmax(0, x[,2] -    75) 
> cat(format(a, use.names=FALSE, style="m"))
  29.25859
  -  3.437775 * max(0,  14.2 - x[,1]) 
  +  5.762954 * max(0, x[,1] -  14.2) 
  + 0.0444337 * x[,1]                  * max(0, x[,2] -    75) 
> a <- earth(Volume ~ Girth*Height, data = trees, pmethod="none")
> cat(format(a))
  25.24205
  -  0.8905681 * h(13.3-Girth)
  +   2.590203 * h(Girth-13.3)
  - 0.02669905 * h(972.7-Girth:Height)
  + 0.03883467 * h(Girth:Height-972.7)
> cat(format(a, colon.char="*"))
  25.24205
  -  0.8905681 * h(13.3-Girth)
  +   2.590203 * h(Girth-13.3)
  - 0.02669905 * h(972.7-Girth*Height)
  + 0.03883467 * h(Girth*Height-972.7)
> cat(format(a, colon.char="*", style="bf"))
  25.24205
  -  0.8905681 * bf1
  +   2.590203 * bf2
  - 0.02669905 * bf3
  + 0.03883467 * bf4

   bf1  h(13.3-Girth)
   bf2  h(Girth-13.3)
   bf3  h(972.7-Girth:Height)
   bf4  h(Girth:Height-972.7)
> a <- lm(Volume ~ ., data = trees)
> cat(format(a)) # basic tests of format.lm
  -57.98766
  +  4.708161 * Girth
  + 0.3392512 * Height
> cat(format(a, digits=4))
  -57.99
  +  4.708 * Girth
  + 0.3393 * Height
> cat(format(a, use.names=FALSE))
  -57.98766
  +  4.708161 * x[,1]
  + 0.3392512 * x[,2]
> cat(format(a, style="p"))
  -57.98766
  +  4.708161 * Girth
  + 0.3392512 * Height
> cat(format(a, use.names=FALSE, style="p"))
  -57.98766
  +  4.708161 * x[,1]
  + 0.3392512 * x[,2]
> a <- lm(Volume ~ Girth*Height, data = trees)
> cat(format(a))
  69.39632
  -  5.855848 * Girth
  -  1.297083 * Height
  + 0.1346544 * Girth:Height
> cat(format(a, colon.char="*"))
  69.39632
  -  5.855848 * Girth
  -  1.297083 * Height
  + 0.1346544 * Girth*Height
> cat("--- mars.to.earth.Rd ----------------------\n")
--- mars.to.earth.Rd ----------------------
> example(mars.to.earth)

mrs.t.> if(require(mda)) {
mrs.t.+     mars.mod <- mars(trees[,-3], trees[,3])
mrs.t.+     earth.mod <- mars.to.earth(mars.mod)
mrs.t.+     # the standard earth functions can now be used
mrs.t.+     # note the reconstructed call in the summary
mrs.t.+     summary(earth.mod, digits = 2)
mrs.t.+ }
Converted mars(x=trees[,-3], y=trees[,3])

to earth(x=trees[,-3], y=trees[,3])

Call: earth(x=trees[,-3], y=trees[,3])

              coefficients
(Intercept)           26.3
h(13.8-Girth)         -3.2
h(Girth-13.8)          6.1
h(11.4-Girth)          0.5

Selected 4 of 8 terms, and 2 of 2 predictors
Termination condition: Unknown
Importance: object has no prune.terms, call update() on the model to fix that
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 10    RSS 190    GRSq 0.96    RSq 0.98
> library(mda)
> mars.mod <- mars(trees[,-3], trees[,3])
> cat("print.default(mars.mod):\n")
print.default(mars.mod):
> print.default(mars.mod)
$call
mars(x = trees[, -3], y = trees[, 3])

$all.terms
[1]  1  2  3  4  5  6  8 10

$selected.terms
[1] 1 2 3 8

$penalty
[1] 2

$degree
[1] 1

$nk
[1] 21

$thresh
[1] 0.001

$gcv
[1] 10.22537

$factor
      Girth Height
 [1,]     0      0
 [2,]     1      0
 [3,]    -1      0
 [4,]     0      1
 [5,]     0     -1
 [6,]     1      0
 [7,]    -1      0
 [8,]     0      1
 [9,]     0     -1
[10,]     0      1
[11,]     0     -1

$cuts
      [,1] [,2]
 [1,]  0.0    0
 [2,] 13.8    0
 [3,] 13.8    0
 [4,]  0.0   75
 [5,]  0.0   75
 [6,] 11.4    0
 [7,] 11.4    0
 [8,]  0.0   72
 [9,]  0.0   72
[10,]  0.0   80
[11,]  0.0   80

$residuals
            [,1]
 [1,]  1.4581315
 [2,]  0.5079983
 [3,] -0.2254239
 [4,]  0.5904880
 [5,] -2.1221305
 [6,] -2.5342186
 [7,] -1.7930674
 [8,] -0.6861328
 [9,]  0.9087137
[10,]  0.3804450
[11,]  2.3729800
[12,]  0.3493344
[13,]  0.7493344
[14,]  1.6899552
[15,] -2.9532435
[16,] -2.2059546
[17,]  3.9194721
[18,] -4.2450607
[19,] -0.2442662
[20,] -1.3609773
[21,]  4.0303181
[22,] -0.9876327
[23,]  4.7646376
[24,] -1.4092887
[25,] -1.4315918
[26,]  3.2647855
[27,]  1.8445232
[28,]  2.9947526
[29,] -4.4165342
[30,] -4.9165342
[31,]  1.7061874

$fitted.values
           [,1]
 [1,]  8.841869
 [2,]  9.792002
 [3,] 10.425424
 [4,] 15.809512
 [5,] 20.922131
 [6,] 22.234219
 [7,] 17.393067
 [8,] 18.886133
 [9,] 21.691286
[10,] 19.519555
[11,] 21.827020
[12,] 20.650666
[13,] 20.650666
[14,] 19.610045
[15,] 22.053243
[16,] 24.405955
[17,] 29.880528
[18,] 31.645061
[19,] 25.944266
[20,] 26.260977
[21,] 30.469682
[22,] 32.687633
[23,] 31.535362
[24,] 39.709289
[25,] 44.031592
[26,] 52.135215
[27,] 53.855477
[28,] 55.305247
[29,] 55.916534
[30,] 55.916534
[31,] 75.293813

$lenb
[1] 11

$coefficients
           [,1]
[1,] 26.2609773
[2,]  6.1128688
[3,] -3.1671107
[4,]  0.4976885

$x
      [,1] [,2] [,3] [,4]
 [1,]    1  0.0  5.5    0
 [2,]    1  0.0  5.2    0
 [3,]    1  0.0  5.0    0
 [4,]    1  0.0  3.3    0
 [5,]    1  0.0  3.1    9
 [6,]    1  0.0  3.0   11
 [7,]    1  0.0  2.8    0
 [8,]    1  0.0  2.8    3
 [9,]    1  0.0  2.7    8
[10,]    1  0.0  2.6    3
[11,]    1  0.0  2.5    7
[12,]    1  0.0  2.4    4
[13,]    1  0.0  2.4    4
[14,]    1  0.0  2.1    0
[15,]    1  0.0  1.8    3
[16,]    1  0.0  0.9    2
[17,]    1  0.0  0.9   13
[18,]    1  0.0  0.5   14
[19,]    1  0.0  0.1    0
[20,]    1  0.0  0.0    0
[21,]    1  0.2  0.0    6
[22,]    1  0.4  0.0    8
[23,]    1  0.7  0.0    2
[24,]    1  2.2  0.0    0
[25,]    1  2.5  0.0    5
[26,]    1  3.5  0.0    9
[27,]    1  3.7  0.0   10
[28,]    1  4.1  0.0    8
[29,]    1  4.2  0.0    8
[30,]    1  4.2  0.0    8
[31,]    1  6.8  0.0   15

attr(,"class")
[1] "mars"
> mars.to.earth.mod <- mars.to.earth(mars.mod)
Converted mars(x=trees[,-3], y=trees[,3])

to earth(x=trees[,-3], y=trees[,3])

> cat("print.default(mars.to.earth.mod):\n")
print.default(mars.to.earth.mod):
> print.default(mars.to.earth.mod)
$rss
[1] 189.9939

$rsq
[1] 0.9765616

$gcv
[1] 10.22537

$grsq
[1] 0.9633775

$bx
      (Intercept) h(Girth-13.8) h(13.8-Girth) h(11.4-Girth)
 [1,]           1           0.0           5.5             0
 [2,]           1           0.0           5.2             0
 [3,]           1           0.0           5.0             0
 [4,]           1           0.0           3.3             0
 [5,]           1           0.0           3.1             9
 [6,]           1           0.0           3.0            11
 [7,]           1           0.0           2.8             0
 [8,]           1           0.0           2.8             3
 [9,]           1           0.0           2.7             8
[10,]           1           0.0           2.6             3
[11,]           1           0.0           2.5             7
[12,]           1           0.0           2.4             4
[13,]           1           0.0           2.4             4
[14,]           1           0.0           2.1             0
[15,]           1           0.0           1.8             3
[16,]           1           0.0           0.9             2
[17,]           1           0.0           0.9            13
[18,]           1           0.0           0.5            14
[19,]           1           0.0           0.1             0
[20,]           1           0.0           0.0             0
[21,]           1           0.2           0.0             6
[22,]           1           0.4           0.0             8
[23,]           1           0.7           0.0             2
[24,]           1           2.2           0.0             0
[25,]           1           2.5           0.0             5
[26,]           1           3.5           0.0             9
[27,]           1           3.7           0.0            10
[28,]           1           4.1           0.0             8
[29,]           1           4.2           0.0             8
[30,]           1           4.2           0.0             8
[31,]           1           6.8           0.0            15

$dirs
              Girth Height
(Intercept)       0      0
h(Girth-13.8)     1      0
h(13.8-Girth)    -1      0
h(Height-75)      0      1
h(75-Height)      0     -1
h(Girth-11.4)     1      0
h(Height-72)      0      1
h(Height-80)      0      1

$cuts
              Girth Height
(Intercept)     0.0      0
h(Girth-13.8)  13.8      0
h(13.8-Girth)  13.8      0
h(Height-75)    0.0     75
h(75-Height)    0.0     75
h(Girth-11.4)  11.4      0
h(Height-72)    0.0     72
h(Height-80)    0.0     80

$selected.terms
[1] 1 2 3 7

$prune.terms
NULL

$fitted.values
              y
 [1,]  8.841869
 [2,]  9.792002
 [3,] 10.425424
 [4,] 15.809512
 [5,] 20.922131
 [6,] 22.234219
 [7,] 17.393067
 [8,] 18.886133
 [9,] 21.691286
[10,] 19.519555
[11,] 21.827020
[12,] 20.650666
[13,] 20.650666
[14,] 19.610045
[15,] 22.053243
[16,] 24.405955
[17,] 29.880528
[18,] 31.645061
[19,] 25.944266
[20,] 26.260977
[21,] 30.469682
[22,] 32.687633
[23,] 31.535362
[24,] 39.709289
[25,] 44.031592
[26,] 52.135215
[27,] 53.855477
[28,] 55.305247
[29,] 55.916534
[30,] 55.916534
[31,] 75.293813

$residuals
            [,1]
 [1,]  1.4581315
 [2,]  0.5079983
 [3,] -0.2254239
 [4,]  0.5904880
 [5,] -2.1221305
 [6,] -2.5342186
 [7,] -1.7930674
 [8,] -0.6861328
 [9,]  0.9087137
[10,]  0.3804450
[11,]  2.3729800
[12,]  0.3493344
[13,]  0.7493344
[14,]  1.6899552
[15,] -2.9532435
[16,] -2.2059546
[17,]  3.9194721
[18,] -4.2450607
[19,] -0.2442662
[20,] -1.3609773
[21,]  4.0303181
[22,] -0.9876327
[23,]  4.7646376
[24,] -1.4092887
[25,] -1.4315918
[26,]  3.2647855
[27,]  1.8445232
[28,]  2.9947526
[29,] -4.4165342
[30,] -4.9165342
[31,]  1.7061874

$coefficients
                       y
(Intercept)   26.2609773
h(Girth-13.8)  6.1128688
h(13.8-Girth) -3.1671107
h(11.4-Girth)  0.4976885

$rss.per.response
[1] 189.9939

$rsq.per.response
[1] 0.9765616

$gcv.per.response
[1] 10.22537

$grsq.per.response
[1] 0.9633775

$rss.per.subset
[1] 8106.0839        NA        NA  189.9939        NA        NA        NA
[8]        NA

$gcv.per.subset
[1] 279.20956        NA        NA  10.22537        NA        NA        NA
[8]        NA

$leverages
 [1] 0.23257376 0.20337574 0.18555587 0.08723624 0.12248572 0.17248005
 [7] 0.07641904 0.05073854 0.08780610 0.04741454 0.06734919 0.04425746
[13] 0.04425746 0.07509704 0.04728244 0.08085017 0.21454775 0.26167636
[19] 0.16017614 0.16788561 0.10621610 0.10955549 0.11166012 0.16467557
[25] 0.07594784 0.09429047 0.10722497 0.12495379 0.13133163 0.13133163
[31] 0.41334716

$pmethod
[1] "backward"

$nprune
NULL

$penalty
[1] 2

$nk
[1] 21

$thresh
[1] 0.001

$call
earth(x = trees[, -3], y = trees[, 3])

$namesx
[1] "Girth"  "Height"

$modvars
       Girth Height
Girth      1      0
Height     0      1

attr(,"class")
[1] "earth"
> printh(mars.to.earth.mod)
===mars.to.earth.mod 
Selected 4 of 8 terms, and 2 of 2 predictors
Termination condition: Unknown
Importance: object has no prune.terms, call update() on the model to fix that
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 10.22537    RSS 189.9939    GRSq 0.9633775    RSq 0.9765616
> printh(summary(mars.to.earth.mod))
===summary(mars.to.earth.mod) 
Call: earth(x=trees[,-3], y=trees[,3])

              coefficients
(Intercept)     26.2609773
h(13.8-Girth)   -3.1671107
h(Girth-13.8)    6.1128688
h(11.4-Girth)    0.4976885

Selected 4 of 8 terms, and 2 of 2 predictors
Termination condition: Unknown
Importance: object has no prune.terms, call update() on the model to fix that
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 10.22537    RSS 189.9939    GRSq 0.9633775    RSq 0.9765616
> printh(summary(mars.to.earth.mod, style="bf"))
===summary(mars.to.earth.mod, style = "bf") 
Call: earth(x=trees[,-3], y=trees[,3])

y =
  26.26098
  -  3.167111 * bf1
  +  6.112869 * bf2
  + 0.4976885 * bf3

   bf1  h(13.8-Girth)
   bf2  h(Girth-13.8)
   bf3  h(11.4-Girth)

Selected 4 of 8 terms, and 2 of 2 predictors
Termination condition: Unknown
Importance: object has no prune.terms, call update() on the model to fix that
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 10.22537    RSS 189.9939    GRSq 0.9633775    RSq 0.9765616
> stopifnot(length(mars.mod$coeff) == length(mars.to.earth.mod$coeff))
> stopifnot(max(mars.mod$coeff - mars.to.earth.mod$coeff) < 1e-10)
> earth.mod <- earth(trees[,-3], trees[,3])
> stopifnot(length(mars.mod$coeff) == length(earth.mod$coeff))
> # coeff differences can be big because forward passes are different
> stopifnot(max(mars.mod$coeff - earth.mod$coeff) < .3)
> 
> par(mfrow=c(3,4), mar=c(4, 3.2, 3, 3), mgp=c(1.6, 0.6, 0), cex = 0.7)
> plot(mars.to.earth.mod, which=c(1,3), do.par=FALSE)
> plotmo(mars.to.earth.mod, do.par=FALSE)
 plotmo grid:    Girth Height
                  12.9     76
> mars.to.earth.mod2 <- update(mars.to.earth.mod)
> plot(mars.to.earth.mod2, which=c(1,3), do.par=FALSE)
> plotmo(mars.to.earth.mod2, do.par=FALSE)
 plotmo grid:    Girth Height
                  12.9     76
> plot(earth.mod, which=c(1,3), do.par=FALSE)
> plotmo(earth.mod, do.par=FALSE)
 plotmo grid:    Girth Height
                  12.9     76
> par(org.par)
> 
> cat("--- plot.earth.models.Rd ----------------------\n")
--- plot.earth.models.Rd ----------------------
> if (PLOT)
+     example(plot.earth.models)

plt.r.> data(ozone1)

plt.r.> a1 <- earth(O3 ~ .,          data = ozone1, degree = 2)

plt.r.> a2 <- earth(O3 ~ .-wind,     data = ozone1, degree = 2)

plt.r.> a3 <- earth(O3 ~ .-humidity, data = ozone1, degree = 2)

plt.r.> plot.earth.models(list(a1,a2,a3), ylim=c(.65,.85))
> cat("--- plot.earth.Rd ----------------------\n")
--- plot.earth.Rd ----------------------
> if (PLOT) {
+     data(etitanic)
+     a <- earth(survived ~ ., data=etitanic, glm=list(family=binomial))
+     par(mfrow=c(2,2))
+     plot(a$glm.list[[1]], caption="a$glm.list[[1]]")
+     example(plot.earth)
+ }

plt.rt> data(ozone1)

plt.rt> earth.mod <- earth(O3 ~ ., data = ozone1, degree = 2)

plt.rt> plot(earth.mod)
> cat("--- predict.earth.Rd ----------------------\n")
--- predict.earth.Rd ----------------------
> example(predict.earth)

prdct.> data(trees)

prdct.> earth.mod <- earth(Volume ~ ., data = trees)

prdct.> predict(earth.mod) # same as earth.mod$fitted.values
         Volume
 [1,]  8.883097
 [2,]  9.909039
 [3,] 10.593000
 [4,] 16.406671
 [5,] 20.578818
 [6,] 22.083528
 [7,] 18.116574
 [8,] 18.116574
 [9,] 21.365376
[10,] 18.800535
[11,] 21.467973
[12,] 20.065861
[13,] 20.065861
[14,] 20.510438
[15,] 21.536380
[16,] 24.614206
[17,] 30.427849
[18,] 32.377136
[19,] 27.350050
[20,] 27.692031
[21,] 30.120085
[22,] 31.966775
[23,] 30.928808
[24,] 40.273079
[25,] 43.304662
[26,] 51.859634
[27,] 53.686902
[28,] 55.015978
[29,] 55.638930
[30,] 55.638930
[31,] 75.905218

prdct.> predict(earth.mod, data.frame(Girth=10, Height=80)) # yields 17.6
       Volume
[1,] 17.60359

prdct.> predict(earth.mod, c(10,80))                        # equivalent
       Volume
[1,] 17.60359
> cat("--- residuals.earth.Rd --------------------\n")
--- residuals.earth.Rd --------------------
> example(residuals.earth)

rsdls.> data(etitanic)

rsdls.> earth.mod <- earth(pclass ~ ., data=etitanic, glm=list(family=binomial))

rsdls.> head(resid(earth.mod, warn=FALSE))      # earth residuals, a column for each response
        1st        2nd        3rd
1 0.6459266 -0.2575797 -0.3883469
2 0.7904775 -0.3372244 -0.4532531
3 1.0316575 -0.3335720 -0.6980855
4 0.7171249 -0.3904317 -0.3266933
5 0.7873520 -0.3970218 -0.3903302
6 0.3628026 -0.2131729 -0.1496297

rsdls.> head(resid(earth.mod, type="response")) # GLM response resids, a column for each response
        1st        2nd        3rd
1 0.6573382 -0.2572600 -0.3595878
2 0.8654089 -0.3490739 -0.4071918
3 0.9669576 -0.3441215 -0.7048640
4 0.7394748 -0.4155799 -0.2598236
5 0.8095001 -0.4246067 -0.3324777
6 0.2959240 -0.2130374 -0.1283785
> cat("--- update.earth.Rd ----------------------\n")
--- update.earth.Rd ----------------------
> example(update.earth)

updt.r> data(ozone1)

updt.r> (earth.mod <- earth(O3 ~ ., data = ozone1, degree = 2))
Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085

updt.r> update(earth.mod, formula = O3 ~ . - temp) # requires forward pass and pruning
Selected 15 of 21 terms, and 8 of 8 predictors
Termination condition: Reached nk 21
Importance: ibt, humidity, doy, vh, dpg, vis, ibh, wind
Number of terms at each degree of interaction: 1 9 5
GCV 13.01626    RSS 3409.313    GRSq 0.7978077    RSq 0.8385391

updt.r> update(earth.mod, nprune = 8)              # requires only pruning
Selected 8 of 21 terms, and 6 of 9 predictors (nprune=8)
Termination condition: Reached nk 21
Importance: temp, humidity, ibh-unused, ibt, doy, dpg, vis, vh-unused, ...
Number of terms at each degree of interaction: 1 5 2
GCV 14.70227    RSS 4323.013    GRSq 0.7716175    RSq 0.7952674

updt.r> update(earth.mod, penalty=1, ponly=TRUE)   # pruning pass only with a new penalty
Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 12.48074    RSS 3693.401    GRSq 0.8061264    RSq 0.825085
> 
> cat("--- evimp.Rd -----------------------------\n")
--- evimp.Rd -----------------------------
> 
> par(mfrow=c(2,2))
> cat('before calling evimp par("mar", "cex"):\n')
before calling evimp par("mar", "cex"):
> print(par("mar", "cex"))
$mar
[1] 5.1 4.1 4.1 2.1

$cex
[1] 0.83

> 
> example(evimp)

evimp> data(ozone1)

evimp> earth.mod <- earth(O3 ~ ., data=ozone1, degree=2)

evimp> ev <- evimp(earth.mod, trim=FALSE)

evimp> plot(ev)

evimp> print(ev)
         nsubsets   gcv    rss
temp           11 100.0  100.0
humidity        9  35.7   38.9
ibt             7  31.6   34.0
doy             7  31.6   34.0
ibh             6  33.4>  36.0>
dpg             6  27.5   29.8
vis             5  21.4   24.1
wind            2  10.3   12.6
vh              1   5.3    7.7
> 
> cat("--- plot.evimp.Rd ------------------------\n")
--- plot.evimp.Rd ------------------------
> 
> example(plot.evimp)

plt.vm> data(ozone1)

plt.vm> earth.mod <- earth(O3 ~ ., data=ozone1, degree=2)

plt.vm> ev <- evimp(earth.mod)

plt.vm> plot(ev)

plt.vm> print(ev)
         nsubsets   gcv    rss
temp           11 100.0  100.0
humidity        9  35.7   38.9
ibt             7  31.6   34.0
doy             7  31.6   34.0
ibh             6  33.4>  36.0>
dpg             6  27.5   29.8
vis             5  21.4   24.1
wind            2  10.3   12.6
vh              1   5.3    7.7
> 
> rownames(ev)[4] <- "a_long_variable_name"
> 
> plot(ev, main="plot.evimp with various options",
+     cex.var = .8,
+     type.nsubsets = "p",
+     col.nsubsets = "red",
+     lty.nsubsets = 2, # ignored because type.nsubsets="p"
+     type.gcv = "l",
+     col.gcv = "green",
+     lty.gcv = 3,
+     type.rss = "b",
+     col.rss = "blue",
+     lty.rss = 4,
+     cex.legend = .8,
+     x.legend = "topright",
+     rh.col = "pink")
> 
> a <- earth(Volume ~ Girth, data = trees)
> plot(evimp(a), main="plot.evimp with single var in model")
> 
> cat('after calling evimp par("mar", "cex"):\n')
after calling evimp par("mar", "cex"):
> print(par("mar", "cex"))
$mar
[1] 5.1 4.1 4.1 2.1

$cex
[1] 0.83

> par(mfrow=c(1,1))
> 
> cat("--- test predict.earth -------------------\n")
--- test predict.earth -------------------
> 
> a <- earth(Volume ~ ., data = trees)
> cat("1a predict(a, c(10,80))\n")
1a predict(a, c(10,80))
> printh(predict(a, c(10,80), trace=1))
===predict(a, c(10, 80), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[1,2]:
  Girth Height
1    10     80
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[1,2]:
  Girth Height
1    10     80
predict.earth with newdata: bx[1,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
predict.earth: returning earth predictions 
       Volume
[1,] 17.60359
> cat("1b predict(a, c(10,10,80,80))\n")
1b predict(a, c(10,10,80,80))
> printh(predict(a, c(10,10,80,80), trace=1))
===predict(a, c(10, 10, 80, 80), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    10     80
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    10     80
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           4.2            5
predict.earth: returning earth predictions 

       Volume
[1,] 17.60359
[2,] 17.60359
> cat("1c predict(a, c(10,11,80,81))\n")
1c predict(a, c(10,11,80,81))
> printh(predict(a, c(10,11,80,81), trace=1))
===predict(a, c(10, 11, 80, 81), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    11     81
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    11     81
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           3.2            6
predict.earth: returning earth predictions 

       Volume
[1,] 17.60359
[2,] 21.60476
> cat("2 predict(a)\n")
2 predict(a)
> printh(head(predict(a, trace=1)))
===head(predict(a, trace = 1)) predict.earth: returning earth fitted.values 

        Volume
[1,]  8.883097
[2,]  9.909039
[3,] 10.593000
[4,] 16.406671
[5,] 20.578818
[6,] 22.083528
> cat("3a predict(a, matrix(c(10,12), nrow=1, ncol=2))\n")
3a predict(a, matrix(c(10,12), nrow=1, ncol=2))
> printh(predict(a, matrix(c(10,12), nrow=1, ncol=2), trace=1))
===predict(a, matrix(c(10, 12), nrow = 1, ncol = 2), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[1,2]:
  Girth Height
1    10     12
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[1,2]:
  Girth Height
1    10     12
predict.earth with newdata: bx[1,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            0
predict.earth: returning earth predictions 
       Volume
[1,] 14.69677
> cat("3b predict(a, matrix(c(10,12), nrow=2, ncol=2, byrow=TRUE)\n")
3b predict(a, matrix(c(10,12), nrow=2, ncol=2, byrow=TRUE)
> printh(predict(a, matrix(c(10,12), nrow=2, ncol=2, byrow=TRUE), trace=1))
===predict(a, matrix(c(10, 12), nrow = 2, ncol = 2, byrow = TRUE),     trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     12
2    10     12
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     12
2    10     12
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            0
2           1             0           4.2            0
predict.earth: returning earth predictions 

       Volume
[1,] 14.69677
[2,] 14.69677
> cat("3c predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2))\n")
3c predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2))
> printh(predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2), trace=1))
===predict(a, matrix(c(10, 12, 80, 90), nrow = 2, ncol = 2), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

       Volume
[1,] 17.60359
[2,] 30.25685
> xpredict <- matrix(c(10,12,80,90), nrow=2, ncol=2)
> colnames(xpredict) <- c("Girth", "Height")
> cat("4 predict(a, xpredict with colnames)\n")
4 predict(a, xpredict with colnames)
> printh(predict(a, xpredict, trace=1))
===predict(a, xpredict, trace = 1) get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

       Volume
[1,] 17.60359
[2,] 30.25685
> cat("5 predict(a, as.data.frame(xpredict with colnames))\n")
5 predict(a, as.data.frame(xpredict with colnames))
> printh(predict(a, as.data.frame(xpredict), trace=1))
===predict(a, as.data.frame(xpredict), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

       Volume
[1,] 17.60359
[2,] 30.25685
> # reverse dataframe columns (and their names), predict should deal with it correctly
> xpredict <- as.data.frame(cbind(xpredict[,2], xpredict[,1]))
> colnames(xpredict) <- c("Height", "Girth")
> cat("6a predict(a, xpredict with reversed columns and colnames)\n")
6a predict(a, xpredict with reversed columns and colnames)
> printh(predict(a, xpredict, trace=1))
===predict(a, xpredict, trace = 1) get.earth.x from model.matrix.earth from predict.earth: x columns are in the wrong order, correcting the column order
    Old columns: Height Girth
    New columns: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

       Volume
[1,] 17.60359
[2,] 30.25685
> xpredict2 <- cbind(xpredict[,1], xpredict[,2]) # nameless matrix
> cat("6b predict(a, xpredict2)\n")
6b predict(a, xpredict2)
> printh(predict(a, xpredict2, trace=1))
===predict(a, xpredict2, trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    80     10
2    90     12
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    80     10
2    90     12
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1          65.8             0            0
2           1          75.8             0            0
predict.earth: returning earth predictions 

       Volume
[1,] 438.9620
[2,] 501.2571
> 
> # repeat but with x,y (not formula) call to earth
> 
> x1 <- cbind(trees$Girth, trees$Height)
> colnames(x1) <- c("Girth", "Height")
> a <- earth(x1, trees$Volume)
> xpredict <- matrix(c(10,12,80,90), nrow=2, ncol=2)
> cat("7a predict(a)\n")
7a predict(a)
> printh(head(predict(a, trace=1)))
===head(predict(a, trace = 1)) predict.earth: returning earth fitted.values 

     trees$Volume
[1,]     8.883097
[2,]     9.909039
[3,]    10.593000
[4,]    16.406671
[5,]    20.578818
[6,]    22.083528
> cat("7n predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2)\n")
7n predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2)
> printh(predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2), trace=1))
===predict(a, matrix(c(10, 12, 80, 90), nrow = 2, ncol = 2), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

     trees$Volume
[1,]     17.60359
[2,]     30.25685
> colnames(xpredict) <- c("Girth", "Height")
> cat("8 predict(a, xpredict with colnames)\n")
8 predict(a, xpredict with colnames)
> printh(predict(a, xpredict, trace=1))
===predict(a, xpredict, trace = 1) get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

     trees$Volume
[1,]     17.60359
[2,]     30.25685
> cat("9 predict(a, as.data.frame(xpredict with colnames))\n")
9 predict(a, as.data.frame(xpredict with colnames))
> printh(predict(a, as.data.frame(xpredict), trace=1))
===predict(a, as.data.frame(xpredict), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

     trees$Volume
[1,]     17.60359
[2,]     30.25685
> cat("--Expect warning from predict.earth: the variable names in 'data' do not match those in 'object'\n")
--Expect warning from predict.earth: the variable names in 'data' do not match those in 'object'
> xpredict2 <- cbind(xpredict[,1], xpredict[,2])
> colnames(xpredict2) <- c("none.such", "joe")
> cat("10a predict(a, xpredict2)\n")
10a predict(a, xpredict2)
> printh(predict(a, xpredict2, trace=1), expect.warning=TRUE)
===predict(a, xpredict2, trace = 1)  expect warning -->get.earth.x from model.matrix.earth from predict.earth: unexpected x column names, renaming columns
    Old names: none.such joe
    New names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 
     trees$Volume
[1,]     17.60359
[2,]     30.25685
> cat("--Expect warning from predict.earth: the variable names in 'data' do not match those in 'object'\n")
--Expect warning from predict.earth: the variable names in 'data' do not match those in 'object'
> xpredict2 <- cbind(xpredict[,1], xpredict[,2])
> colnames(xpredict2) <- c("Height", "Girth") # reversed
> cat("10b predict(a, xpredict2)\n")
10b predict(a, xpredict2)
> printh(predict(a, xpredict2, trace=1), expect.warning=TRUE)
===predict(a, xpredict2, trace = 1)  expect warning -->get.earth.x from model.matrix.earth from predict.earth: x columns are in the wrong order, correcting the column order
    Old columns: Height Girth
    New columns: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    80     10
2    90     12
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1          65.8             0            0
2           1          75.8             0            0
predict.earth: returning earth predictions 
     trees$Volume
[1,]     438.9620
[2,]     501.2571
> 
> cat("--- test predict.earth with multiple response models-------------------\n")
--- test predict.earth with multiple response models-------------------
> 
> a <- earth(cbind(Volume, Volume + 100) ~ ., data = trees)
> cat("1a predict(a, c(10,80))\n")
1a predict(a, c(10,80))
> printh(predict(a, c(10,80), trace=1))
===predict(a, c(10, 80), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[1,2]:
  Girth Height
1    10     80
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[1,2]:
  Girth Height
1    10     80
predict.earth with newdata: bx[1,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
predict.earth: returning earth predictions 
       Volume cbind(Volume, Volume + 100)2
[1,] 17.60359                     117.6036
> predict.a1a <- predict(a, c(10,80))
> check.almost.equal(predict.a1a[1,1], 17.6035895926138, msg="predict.a1a[1,1]")
> check.almost.equal(predict.a1a[1,2], 117.603589592614, msg="predict.a1a[1,2]")
> cat("1b predict(a, c(10,10,80,80))\n")
1b predict(a, c(10,10,80,80))
> printh(predict(a, c(10,10,80,80), trace=1))
===predict(a, c(10, 10, 80, 80), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    10     80
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    10     80
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           4.2            5
predict.earth: returning earth predictions 

       Volume cbind(Volume, Volume + 100)2
[1,] 17.60359                     117.6036
[2,] 17.60359                     117.6036
> cat("1c predict(a, c(10,11,80,81))\n")
1c predict(a, c(10,11,80,81))
> printh(predict(a, c(10,11,80,81), trace=1))
===predict(a, c(10, 11, 80, 81), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    11     81
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    11     81
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           3.2            6
predict.earth: returning earth predictions 

       Volume cbind(Volume, Volume + 100)2
[1,] 17.60359                     117.6036
[2,] 21.60476                     121.6048
> cat("1d predict(a, data.frame=c(Girth=10,Height=80))\n")
1d predict(a, data.frame=c(Girth=10,Height=80))
> printh(predict(a, newdata=data.frame(Girth=10,Height=80)))
===predict(a, newdata = data.frame(Girth = 10, Height = 80))        Volume cbind(Volume, Volume + 100)2
[1,] 17.60359                     117.6036
> predict.a1d <- predict(a, newdata=data.frame(Girth=10,Height=80))
> check.almost.equal(predict.a1d[1,1], 17.6035895926138, msg="predict.a1d[1,1]")
> check.almost.equal(predict.a1d[1,2], 117.603589592614, msg="predict.a1d[1,2]")
> expect.err(try(predict(a, newdata=10)), "Could not convert vector x to matrix because length(x) 1\n       is not a multiple of the number 2 of predictors")
Error : Could not convert vector x to matrix because length(x) 1
       is not a multiple of the number 2 of predictors 
       Expected predictors: "Girth", "Height"
Got expected error from try(predict(a, newdata = 10))
> cat("2 predict(a)\n")
2 predict(a)
> printh(head(predict(a, trace=1)))
===head(predict(a, trace = 1)) predict.earth: returning earth fitted.values 

        Volume cbind(Volume, Volume + 100)2
[1,]  8.883097                     108.8831
[2,]  9.909039                     109.9090
[3,] 10.593000                     110.5930
[4,] 16.406671                     116.4067
[5,] 20.578818                     120.5788
[6,] 22.083528                     122.0835
> cat("3a predict(a, matrix(c(10,12), nrow=1, ncol=2))\n")
3a predict(a, matrix(c(10,12), nrow=1, ncol=2))
> printh(predict(a, matrix(c(10,12), nrow=1, ncol=2), trace=1))
===predict(a, matrix(c(10, 12), nrow = 1, ncol = 2), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[1,2]:
  Girth Height
1    10     12
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[1,2]:
  Girth Height
1    10     12
predict.earth with newdata: bx[1,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            0
predict.earth: returning earth predictions 
       Volume cbind(Volume, Volume + 100)2
[1,] 14.69677                     114.6968
> cat("3b predict(a, matrix(c(10,12), nrow=2, ncol=2, byrow=TRUE)\n")
3b predict(a, matrix(c(10,12), nrow=2, ncol=2, byrow=TRUE)
> printh(predict(a, matrix(c(10,12), nrow=2, ncol=2, byrow=TRUE), trace=1))
===predict(a, matrix(c(10, 12), nrow = 2, ncol = 2, byrow = TRUE),     trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     12
2    10     12
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     12
2    10     12
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            0
2           1             0           4.2            0
predict.earth: returning earth predictions 

       Volume cbind(Volume, Volume + 100)2
[1,] 14.69677                     114.6968
[2,] 14.69677                     114.6968
> cat("3c predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2))\n")
3c predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2))
> printh(predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2), trace=1))
===predict(a, matrix(c(10, 12, 80, 90), nrow = 2, ncol = 2), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

       Volume cbind(Volume, Volume + 100)2
[1,] 17.60359                     117.6036
[2,] 30.25685                     130.2568
> xpredict <- matrix(c(10,12,80,90), nrow=2, ncol=2)
> colnames(xpredict) <- c("Girth", "Height")
> cat("4 predict(a, xpredict with colnames)\n")
4 predict(a, xpredict with colnames)
> printh(predict(a, xpredict, trace=1))
===predict(a, xpredict, trace = 1) get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

       Volume cbind(Volume, Volume + 100)2
[1,] 17.60359                     117.6036
[2,] 30.25685                     130.2568
> cat("5 predict(a, as.data.frame(xpredict with colnames))\n")
5 predict(a, as.data.frame(xpredict with colnames))
> printh(predict(a, as.data.frame(xpredict), trace=1))
===predict(a, as.data.frame(xpredict), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

       Volume cbind(Volume, Volume + 100)2
[1,] 17.60359                     117.6036
[2,] 30.25685                     130.2568
> # reverse dataframe columns (and their names), predict should deal with it correctly
> xpredict <- as.data.frame(cbind(xpredict[,2], xpredict[,1]))
> colnames(xpredict) <- c("Height", "Girth")
> cat("6 predict(a, xpredict with reversed columns and colnames)\n")
6 predict(a, xpredict with reversed columns and colnames)
> printh(predict(a, xpredict, trace=1))
===predict(a, xpredict, trace = 1) get.earth.x from model.matrix.earth from predict.earth: x columns are in the wrong order, correcting the column order
    Old columns: Height Girth
    New columns: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

       Volume cbind(Volume, Volume + 100)2
[1,] 17.60359                     117.6036
[2,] 30.25685                     130.2568
> expect.err(try(predict(a, interval="pin")), "no prediction intervals because the earth model was not built with varmod.method")
Error : no prediction intervals because the earth model was not built with varmod.method
Got expected error from try(predict(a, interval = "pin"))
> expect.err(try(earth(cbind(Volume, Volume + 100) ~ ., data = trees, nfold=3, ncross=3, varmod.method="lm")), "variance models are not supported for multiple response models")
Error : variance models are not supported for multiple response models
Got expected error from try(earth(cbind(Volume, Volume + 100) ~ ., data = trees, nfold = 3,     ncross = 3, varmod.method = "lm"))
> 
> options(warn=2)
> # TODO column naming for the following maybe needs work?
> #      nresponse="cbind(Volume, Volume + 100)2"  is confusing (2 should be in brackets?)
> expect.err(try(plot(a)), "Defaulting to nresponse=1, see above messages")

predict.earth[31,2]:
       Volume cbind(Volume, Volume + 100)2
1    8.883097                     108.8831
2    9.909039                     109.9090
3   10.593000                     110.5930
... 16.406671                     116.4067
31  75.905218                     175.9052

predict.earth returned multiple columns (see above) but nresponse is not specified
    Use the nresponse argument to specify a column.
         Example: nresponse=2
         Example: nresponse="cbind(Volume, Volume + 100)2"

Error : (converted from warning) Defaulting to nresponse=1, see above messages
Got expected error from try(plot(a))
> options(warn=1)
> 
> # repeat but with x,y (not formula) call to earth
> 
> x1 <- cbind(trees$Girth, trees$Height)
> colnames(x1) <- c("Girth", "Height")
> a <- earth(x1, cbind(trees$Volume, trees$Volume+100))
> xpredict <- matrix(c(10,12,80,90), nrow=2, ncol=2)
> cat("7a predict(a)\n")
7a predict(a)
> printh(head(predict(a, trace=1)))
===head(predict(a, trace = 1)) predict.earth: returning earth fitted.values 

            y1       y2
[1,]  8.883097 108.8831
[2,]  9.909039 109.9090
[3,] 10.593000 110.5930
[4,] 16.406671 116.4067
[5,] 20.578818 120.5788
[6,] 22.083528 122.0835
> cat("7b predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2)\n")
7b predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2)
> printh(predict(a, matrix(c(10,12,80,90), nrow=2, ncol=2), trace=1))
===predict(a, matrix(c(10, 12, 80, 90), nrow = 2, ncol = 2), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x has no column names, adding column names: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

           y1       y2
[1,] 17.60359 117.6036
[2,] 30.25685 130.2568
> colnames(xpredict) <- c("Girth", "Height")
> cat("8 predict(a, xpredict with colnames)\n")
8 predict(a, xpredict with colnames)
> printh(predict(a, xpredict, trace=1))
===predict(a, xpredict, trace = 1) get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

           y1       y2
[1,] 17.60359 117.6036
[2,] 30.25685 130.2568
> cat("9 predict(a, as.data.frame(xpredict with colnames))\n")
9 predict(a, as.data.frame(xpredict with colnames))
> printh(predict(a, as.data.frame(xpredict), trace=1))
===predict(a, as.data.frame(xpredict), trace = 1) get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 

           y1       y2
[1,] 17.60359 117.6036
[2,] 30.25685 130.2568
> cat("--Expect warning from predict.earth: the variable names in 'data' do not match those in 'object'\n")
--Expect warning from predict.earth: the variable names in 'data' do not match those in 'object'
> xpredict <- as.data.frame(cbind(xpredict[,2], xpredict[,1]))
> colnames(xpredict) <- c("Height", "Girth")
> cat("10 predict(a, xpredict)\n")
10 predict(a, xpredict)
> printh(predict(a, xpredict, trace=1), expect.warning=TRUE)
===predict(a, xpredict, trace = 1)  expect warning -->get.earth.x from model.matrix.earth from predict.earth: x columns are in the wrong order, correcting the column order
    Old columns: Height Girth
    New columns: Girth Height
get.earth.x from model.matrix.earth from predict.earth: x[2,2]:
  Girth Height
1    10     80
2    12     90
predict.earth with newdata: bx[2,4]:
  (Intercept) h(Girth-14.2) h(14.2-Girth) h(Height-75)
1           1             0           4.2            5
2           1             0           2.2           15
predict.earth: returning earth predictions 
           y1       y2
[1,] 17.60359 117.6036
[2,] 30.25685 130.2568
> 
> cat("--- earth.predict with NAs, with formula interface ---\n")
--- earth.predict with NAs, with formula interface ---
> 
> predict.with.message <- function(message, earth.model, newdata) {
+     cat("predict.earth  ", message, ":\n", sep="")
+     print(predict(earth.model, newdata=newdata, trace=1))
+     cat("\n")
+ }
> 
> iris.earth <- earth(Petal.Width ~ Sepal.Length + Sepal.Width + Petal.Length, data=iris)
> x <- iris[1,]
> predict.with.message("formula interface and vector", iris.earth, newdata=x)
predict.earth  formula interface and vector:
get.earth.x from model.matrix.earth from predict.earth: x[1,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[1,3]:
  Sepal.Length Sepal.Width Petal.Length
1          5.1         3.5          1.4
predict.earth with newdata: bx[1,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                  0                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
predict.earth: returning earth predictions 
     Petal.Width
[1,]   0.2562505

> x$Sepal.Width <- as.numeric(NA)
> predict.with.message("formula interface and vector with NA", iris.earth, newdata=x)
predict.earth  formula interface and vector with NA:
get.earth.x from model.matrix.earth from predict.earth: x[1,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1          NA          1.4         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[1,3]:
  Sepal.Length Sepal.Width Petal.Length
1          5.1          NA          1.4
predict.earth with newdata: bx[1,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                 NA                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
predict.earth: returning earth predictions 
     Petal.Width
[1,]          NA

> x <- iris[1,]
> x$Petal.Width <- as.numeric(NA) # Petal.Width is unused in the earth model
> predict.with.message("formula interface and vector with NA in unused variable", iris.earth, newdata=x)
predict.earth  formula interface and vector with NA in unused variable:
get.earth.x from model.matrix.earth from predict.earth: x[1,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4          NA  setosa
  Species is a factor with levels: setosa versicolor virginica
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[1,3]:
  Sepal.Length Sepal.Width Petal.Length
1          5.1         3.5          1.4
predict.earth with newdata: bx[1,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                  0                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
predict.earth: returning earth predictions 
     Petal.Width
[1,]   0.2562505

> 
> x <- iris[1:3,]
> predict.with.message("formula interface and matrix", iris.earth, newdata=x)
predict.earth  formula interface and matrix:
get.earth.x from model.matrix.earth from predict.earth: x[3,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[3,3]:
  Sepal.Length Sepal.Width Petal.Length
1          5.1         3.5          1.4
2          4.9         3.0          1.4
3          4.7         3.2          1.3
predict.earth with newdata: bx[3,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                0.0                   0
2           1               4.6                0.5                   0
3           1               4.7                0.3                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
2                 2.0                   0                   0
3                 2.2                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
2                   0                   0
3                   0                   0
predict.earth: returning earth predictions 
     Petal.Width
[1,]   0.2562505
[2,]   0.1733787
[3,]   0.1880121

> x[2,]$Sepal.Width <- as.numeric(NA)
> predict.with.message("formula interface and matrix with NA", iris.earth, newdata=x)
predict.earth  formula interface and matrix with NA:
get.earth.x from model.matrix.earth from predict.earth: x[3,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9          NA          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[3,3]:
  Sepal.Length Sepal.Width Petal.Length
1          5.1         3.5          1.4
2          4.9          NA          1.4
3          4.7         3.2          1.3
predict.earth with newdata: bx[3,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                0.0                   0
2           1               4.6                 NA                   0
3           1               4.7                0.3                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
2                 2.0                   0                   0
3                 2.2                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
2                   0                   0
3                   0                   0
predict.earth: returning earth predictions 
     Petal.Width
[1,]   0.2562505
[2,]          NA
[3,]   0.1880121

> x <- iris[1:3,]
> x[2,]$Petal.Width <- as.numeric(NA) # Petal.Width is unused in the earth model
> predict.with.message("formula interface and matrix with NA in unused variable", iris.earth, newdata=x)
predict.earth  formula interface and matrix with NA in unused variable:
get.earth.x from model.matrix.earth from predict.earth: x[3,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4          NA  setosa
3          4.7         3.2          1.3         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
get.earth.x from model.matrix.earth from predict.earth: after call to model.frame: mf[3,3]:
  Sepal.Length Sepal.Width Petal.Length
1          5.1         3.5          1.4
2          4.9         3.0          1.4
3          4.7         3.2          1.3
predict.earth with newdata: bx[3,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                0.0                   0
2           1               4.6                0.5                   0
3           1               4.7                0.3                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
2                 2.0                   0                   0
3                 2.2                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
2                   0                   0
3                   0                   0
predict.earth: returning earth predictions 
     Petal.Width
[1,]   0.2562505
[2,]   0.1733787
[3,]   0.1880121

> 
> cat("--- earth.predict with NAs, with xy interface ---\n")
--- earth.predict with NAs, with xy interface ---
> 
> iris.earth <- earth(iris[,1:3], iris[,4])
> x <- iris[1,]
> predict.with.message("default interface and vector", iris.earth, newdata=x) # tests the "Fix: April 2010" in get.earthx()
predict.earth  default interface and vector:
get.earth.x from model.matrix.earth from predict.earth: x[1,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
predict.earth with newdata: bx[1,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                  0                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
predict.earth: returning earth predictions 
     iris[, 4]
[1,] 0.2562505

> x$Sepal.Width <- as.numeric(NA)
> predict.with.message("default interface and vector with NA", iris.earth, newdata=x)
predict.earth  default interface and vector with NA:
get.earth.x from model.matrix.earth from predict.earth: x[1,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1          NA          1.4         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
predict.earth with newdata: bx[1,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                 NA                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
predict.earth: returning earth predictions 
     iris[, 4]
[1,]        NA

> x <- iris[1,]
> x$Petal.Width <- as.numeric(NA) # Petal.Width is unused in the earth model
> predict.with.message("default interface and vector with NA in unused variable", iris.earth, newdata=x)
predict.earth  default interface and vector with NA in unused variable:
get.earth.x from model.matrix.earth from predict.earth: x[1,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4          NA  setosa
  Species is a factor with levels: setosa versicolor virginica
predict.earth with newdata: bx[1,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                  0                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
predict.earth: returning earth predictions 
     iris[, 4]
[1,] 0.2562505

> 
> x <- iris[1:3,]
> predict.with.message("default interface and matrix", iris.earth, newdata=x)
predict.earth  default interface and matrix:
get.earth.x from model.matrix.earth from predict.earth: x[3,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
predict.earth with newdata: bx[3,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                0.0                   0
2           1               4.6                0.5                   0
3           1               4.7                0.3                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
2                 2.0                   0                   0
3                 2.2                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
2                   0                   0
3                   0                   0
predict.earth: returning earth predictions 
     iris[, 4]
[1,] 0.2562505
[2,] 0.1733787
[3,] 0.1880121

> x[2,]$Sepal.Width <- as.numeric(NA)
> predict.with.message("default interface and matrix with NA", iris.earth, newdata=x)
predict.earth  default interface and matrix with NA:
get.earth.x from model.matrix.earth from predict.earth: x[3,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9          NA          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
predict.earth with newdata: bx[3,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                0.0                   0
2           1               4.6                 NA                   0
3           1               4.7                0.3                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
2                 2.0                   0                   0
3                 2.2                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
2                   0                   0
3                   0                   0
predict.earth: returning earth predictions 
     iris[, 4]
[1,] 0.2562505
[2,]        NA
[3,] 0.1880121

> x <- iris[1:3,]
> x[2,]$Petal.Width <- as.numeric(NA) # Petal.Width is unused in the earth model
> predict.with.message("default interface and matrix with NA in unused variable", iris.earth, newdata=x)
predict.earth  default interface and matrix with NA in unused variable:
get.earth.x from model.matrix.earth from predict.earth: x[3,5]:
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4          NA  setosa
3          4.7         3.2          1.3         0.2  setosa
  Species is a factor with levels: setosa versicolor virginica
predict.earth with newdata: bx[3,9]:
  (Intercept) h(6-Petal.Length) h(3.5-Sepal.Width) h(Sepal.Length-6.9)
1           1               4.6                0.0                   0
2           1               4.6                0.5                   0
3           1               4.7                0.3                   0
  h(6.9-Sepal.Length) h(Sepal.Length-7.2) h(Petal.Length-5.3)
1                 1.8                   0                   0
2                 2.0                   0                   0
3                 2.2                   0                   0
  h(Petal.Length-4.7) h(Petal.Length-5.5)
1                   0                   0
2                   0                   0
3                   0                   0
predict.earth: returning earth predictions 
     iris[, 4]
[1,] 0.2562505
[2,] 0.1733787
[3,] 0.1880121

> 
> cat("--- test reorder.earth ----------------------\n")
--- test reorder.earth ----------------------
> a <- earth(O3 ~ ., data = ozone1, degree = 2)
> earth:::reorder.earth(a, decomp = "none")
 [1]  1  2  3  4  5  6  7  8  9 10 11 12
> earth:::reorder.earth(a)   # defaults to decomp = "anova"
 [1]  1  2 10  8  5  4 12  9  3  6  7 11
> a$selected.terms[earth:::reorder.earth(a)]
 [1]  1  2 17 13  9  8 21 14  7 10 11 19
> 
> cat("--- tests with ozone data ----------------------\n")
--- tests with ozone data ----------------------
> 
> ozone.test <- function(itest, sModel, x, y, degree=2, nk=51,
+                     plotit=PLOT, trace=0, smooth.col="red", print.mars=FALSE)
+ {
+     fite <- earth(x, y, degree=degree, nk=nk, trace=trace)
+     fitm <- mars(x, y, degree=degree, nk=nk)
+     fitme <- mars.to.earth(fitm)
+ 
+     cat("itest",
+         sprint("%-3d", itest),
+         sprint("%-32s", sModel),
+         "degree",   sprint("%-2d",  degree), "nk", sprint("%-3g", nk),
+         "nTerms",   sprint("%-2d",  sum(fite$selected.terms != 0)),
+         "of",       sprint("%-3d",  nrow(fite$dirs)),
+         "RSq",      sprint("%4.2g", fite$rsq),
+         "GRSq",     sprint("%4.2g", fite$grsq),
+         "mars RSq", sprint("%4.2g", fitme$rsq),
+         "ratio",    sprint("%.2f",  fite$rsq / fitme$rsq),
+         "GRSq",     sprint("%4.2g", fitme$grsq),
+         "ratio",    sprint("%.2f",  fite$grsq / fitme$grsq),
+         "\n")
+     if(print.mars) {
+         fitme1 <- update(fitme) # generate model selection data
+         printh(summary(fitme1))
+         cat("\n")
+     }
+     printh(summary(fite))
+     if(plotit) {
+         caption <- paste("itest ", itest, ": ", sModel, " degree=", degree, " nk=", nk, sep="")
+         plotmo(fite, caption=paste("EARTH", caption), trace=-1)
+         plotmo(fitme, caption=paste("MARS", caption), trace=-1)
+         plot(fite, npoints=500, smooth.col=smooth.col, caption=paste("EARTH", caption), info=TRUE)
+         plot(fitme, caption=paste("MARS", caption), info=TRUE)
+         fitme <- update(fitme)  # generate model selection data
+         plot.earth.models(list(fite, fitme), caption=paste(itest, ": Compare earth to mars ", sModel, sep=""))
+     }
+     fite
+ }
> data(ozone1)
> attach(ozone1)
> 
> x.global <- cbind(wind, humidity, temp, vis)
> y <- doy
> itest <- 1; ozone.test(itest, "doy ~ wind+humidity+temp+vis", x.global, y, degree=1, nk=21)
Converted mars(x=x, y=y, degree=degree, nk=nk)

to earth(x=x, y=y, degree=degree, nk=nk)

itest 1   doy ~ wind+humidity+temp+vis     degree 1  nk 21  nTerms 7  of 15  RSq 0.26 GRSq  0.2 mars RSq 0.21 ratio 1.25 GRSq 0.17 ratio 1.21 
===summary(fite) 
Call: earth(x=x, y=y, trace=trace, degree=degree, nk=nk)

               coefficients
(Intercept)       68.211814
h(3-wind)         58.202580
h(28-humidity)     8.904095
h(humidity-28)     1.514544
h(temp-45)        45.704313
h(temp-48)      -118.146795
h(temp-49)        73.558997

Selected 7 of 15 terms, and 3 of 4 predictors
Termination condition: Reached nk 21
Importance: wind, temp, humidity, vis-unused
Number of terms at each degree of interaction: 1 6 (additive model)
GCV 8737.327    RSS 2660622    GRSq 0.2004306    RSq 0.2576942
Selected 7 of 15 terms, and 3 of 4 predictors
Termination condition: Reached nk 21
Importance: wind, temp, humidity, vis-unused
Number of terms at each degree of interaction: 1 6 (additive model)
GCV 8737.327    RSS 2660622    GRSq 0.2004306    RSq 0.2576942
> 
> x.global <- cbind(wind, humidity, temp, vis)
> y <- doy
> itest <- itest+1; a91 <- ozone.test(itest, "doy ~ wind+humidity+temp+vis", x.global, y, degree=2, nk=21)
Converted mars(x=x, y=y, degree=degree, nk=nk)

to earth(x=x, y=y, degree=degree, nk=nk)

itest 2   doy ~ wind+humidity+temp+vis     degree 2  nk 21  nTerms 10 of 20  RSq 0.28 GRSq 0.17 mars RSq 0.26 ratio 1.10 GRSq 0.18 ratio 0.94 
===summary(fite) 
Call: earth(x=x, y=y, trace=trace, degree=degree, nk=nk)

                            coefficients
(Intercept)                   130.291709
h(3-wind)                      56.324090
h(28-humidity)                 15.639545
h(humidity-28)                  2.108507
h(49-temp)                     -8.918573
h(wind-3) * h(44-temp)          1.473267
h(23-humidity) * h(temp-49)    -4.977131
h(28-humidity) * h(temp-53)     1.856655
h(humidity-28) * h(vis-200)    -0.022851
h(temp-49) * h(vis-120)         0.024712

Selected 10 of 20 terms, and 4 of 4 predictors
Termination condition: Reached nk 21
Importance: wind, temp, humidity, vis
Number of terms at each degree of interaction: 1 4 5
GCV 9046.094    RSS 2575183    GRSq 0.1721748    RSq 0.2815314
> 
> # this is a basic test of RegressAndFix (because this generates lin dep bx cols)
> 
> cat("--Expect warning from mda::mars: NAs introduced by coercion\n") # why do we get a warning?
--Expect warning from mda::mars: NAs introduced by coercion
> x.global <- cbind(wind, exp(humidity))
> y <- doy
> # smooth.col is 0 else get loess errors
> # trace==2 so we see "Fixed rank deficient bx by removing 2 terms, 7 terms remain"
> itest <- itest+1; ozone.test(itest, "doy ~ wind+exp(humidity)", x.global, y, degree=1, nk=21, smooth.col=0, trace=2)
x[330,2] with colnames wind x2
y[330,1] with colname y, and values 33, 34, 35, 36, 37, 38, 39, 4...
Forward pass: minspan 5 endspan 8   x[330,2] 5.16 kB   bx[330,21] 54.1 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0887 0.1107       0.1107    1         wind           3  2   3         1 
4      0.0906 0.1235      0.01274    1         wind           9  4             1 
6      0.0821 0.1262     0.002668    1         wind           4  5             1 
8      0.0730 0.1285     0.002307    1         wind           6  6             1 
10     0.0633 0.1304     0.001925    2           x2  1.7848e+08< 7             1 
12     0.0534 0.1323     0.001868    2           x2  1.7848e+08< 8             1 
14     0.0432 0.1340     0.001792    2           x2  1.7848e+08< 9             1 
16     0.0309 0.1340            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 15 terms, 9 terms used (DeltaRSq 0)
After forward pass GRSq 0.031 RSq 0.134
Forward pass complete: 15 terms, 9 terms used
Fixed rank deficient bx by removing 2 terms, 7 terms remain
Prune backward penalty 2 nprune null: selected 3 of 7 terms, and 1 of 2 preds
After pruning pass GRSq 0.101 RSq 0.123
Warning in storage.mode(tagx) <- "integer" :
  NAs introduced by coercion to integer range
Converted mars(x=x, y=y, degree=degree, nk=nk)

to earth(x=x, y=y, degree=degree, nk=nk)

itest 3   doy ~ wind+exp(humidity)         degree 1  nk 21  nTerms 3  of 7   RSq 0.12 GRSq  0.1 mars RSq 0.099 ratio 1.24 GRSq 0.077 ratio 1.32 
===summary(fite) 
Call: earth(x=x, y=y, trace=trace, degree=degree, nk=nk)

            coefficients
(Intercept)    202.17924
h(3-wind)       50.04004
h(wind-9)      -61.15513

Selected 3 of 7 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 7 terms
Importance: wind, x2-unused
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 9821.564    RSS 3143644    GRSq 0.1012101    RSq 0.1229323
Selected 3 of 7 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 7 terms
Importance: wind, x2-unused
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 9821.564    RSS 3143644    GRSq 0.1012101    RSq 0.1229323
> 
> x.global <- cbind(vh,wind,humidity,temp,ibh,dpg,ibt,vis,doy)
> y <- O3
> itest <- itest+1; ozone.test(itest, "O3~.", x.global, y, degree=2, nk=21)
Converted mars(x=x, y=y, degree=degree, nk=nk)

to earth(x=x, y=y, degree=degree, nk=nk)

itest 4   O3~.                             degree 2  nk 21  nTerms 12 of 21  RSq 0.83 GRSq 0.79 mars RSq 0.82 ratio 1.01 GRSq 0.78 ratio 1.01 
===summary(fite) 
Call: earth(x=x, y=y, trace=trace, degree=degree, nk=nk)

                            coefficients
(Intercept)                   13.2169900
h(temp-58)                     0.3726072
h(194-ibt)                    -0.0455100
h(200-vis)                     0.0222462
h(96-doy)                     -0.1223029
h(doy-96)                     -0.0240235
h(5730-vh) * h(temp-58)       -0.0104496
h(wind-7) * h(200-vis)        -0.0180898
h(55-humidity) * h(temp-58)   -0.0222754
h(temp-58) * h(dpg-52)        -0.0168249
h(temp-58) * h(52-dpg)         0.0041232
h(1105-ibh) * h(21-dpg)       -0.0001022

Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
> 
> x.global <- cbind(vh,wind,humidity,temp,ibh,dpg,ibt,vis,doy)
> y <- O3
> itest <- itest+1; ozone.test(itest, "O3~., nk=51", x.global, y, degree=2, nk=51, print.mars=TRUE)
Converted mars(x=x, y=y, degree=degree, nk=nk)

to earth(x=x, y=y, degree=degree, nk=nk)

itest 5   O3~., nk=51                      degree 2  nk 51  nTerms 25 of 46  RSq 0.87 GRSq 0.81 mars RSq 0.86 ratio 1.01 GRSq  0.8 ratio 1.01 
===summary(fitme1) 
Call: earth(x=x, y=y, degree=degree, nk=nk, Object=fitme)

                             coefficients
(Intercept)                    13.1186756
h(56-humidity)                 -0.1031673
h(humidity-56)                 -0.1085360
h(dpg-8)                       -0.0587153
h(125-ibt)                     -0.0434807
h(ibt-125)                      0.0626181
h(ibt-194)                     -0.0655497
h(90-vis)                       0.0508188
h(96-doy)                      -0.1101954
h(doy-158)                     -0.0561658
h(vh-5890) * h(humidity-56)     0.0164870
h(vh-5760) * h(1049-ibh)        0.0000837
h(wind-4) * h(90-vis)          -0.0209123
h(humidity-56) * h(1571-ibh)   -0.0001258
h(humidity-28) * h(8-dpg)      -0.0023565
h(humidity-41) * h(ibt-125)     0.0029711
h(1049-ibh) * h(60-dpg)        -0.0000749
h(dpg-52) * h(ibt-194)         -0.0102805
h(ibt-242) * h(90-vis)          0.0041764
h(ibt-261) * h(90-vis)         -0.0096904
h(295-ibt) * h(doy-158)         0.0001535
h(ibt-295) * h(doy-158)         0.0028195

Selected 22 of 48 terms, and 8 of 9 predictors
Termination condition: Unknown
Importance: humidity, ibt, doy, ibh, dpg, vh, vis, wind, temp-unused
Number of terms at each degree of interaction: 1 9 12
GCV 12.6843    RSS 2938.616    GRSq 0.8029643    RSq 0.8608307

===summary(fite) 
Call: earth(x=x, y=y, trace=trace, degree=degree, nk=nk)

                            coefficients
(Intercept)                    68.254338
h(temp-58)                      0.361808
h(10-dpg)                      -0.037457
h(dpg-10)                      -0.043446
h(ibt-281)                      0.276811
h(vis-17)                      -0.293855
h(200-vis)                     -0.247686
h(vis-200)                      0.321231
h(96-doy)                      -0.111486
h(doy-96)                      -0.023111
h(5730-vh) * h(temp-58)        -0.009559
h(vh-5850) * h(doy-96)          0.000494
h(wind-7) * h(200-vis)         -0.012406
h(55-humidity) * h(temp-58)    -0.018386
h(humidity-55) * h(temp-58)     0.005696
h(temp-71) * h(1105-ibh)        0.000423
h(temp-58) * h(dpg-52)         -0.013575
h(temp-72) * h(doy-96)         -0.003615
h(1105-ibh) * h(21-dpg)        -0.000100
h(ibt-194) * h(vis-80)          0.014133
h(ibt-194) * h(vis-70)         -0.008274
h(ibt-194) * h(vis-100)        -0.006492
h(230-ibt) * h(vis-17)         -0.000179
h(260-ibt) * h(200-vis)        -0.000331
h(ibt-260) * h(200-vis)        -0.001086

Selected 25 of 46 terms, and 9 of 9 predictors
Termination condition: Reached nk 51
Importance: temp, ibt, vis, doy, ibh, dpg, humidity, wind, vh
Number of terms at each degree of interaction: 1 9 15
GCV 12.35626    RSS 2709.428    GRSq 0.80806    RSq 0.8716848
Selected 25 of 46 terms, and 9 of 9 predictors
Termination condition: Reached nk 51
Importance: temp, ibt, vis, doy, ibh, dpg, humidity, wind, vh
Number of terms at each degree of interaction: 1 9 15
GCV 12.35626    RSS 2709.428    GRSq 0.80806    RSq 0.8716848
> 
> detach(ozone1)
> 
> cat("--- fast mars -----------------------------------\n")
--- fast mars -----------------------------------
> 
> printh(earth(O3 ~ ., data=ozone1, degree=2, nk = 31, fast.k = 0, fast.beta = 1))
===earth(O3 ~ ., data = ozone1, degree = 2, nk = 31, fast.k = 0,     fast.beta = 1) 
Selected 15 of 31 terms, and 9 of 9 predictors
Termination condition: Reached nk 31
Importance: temp, ibt, humidity, doy, dpg, vis, wind, ibh, vh
Number of terms at each degree of interaction: 1 5 9
GCV 13.22659    RSS 3464.405    GRSq 0.7945405    RSq 0.83593
> printh(earth(O3 ~ ., data=ozone1, degree=2, nk = 31, fast.k = 0, fast.beta = 0))
===earth(O3 ~ ., data = ozone1, degree = 2, nk = 31, fast.k = 0,     fast.beta = 0) 
Selected 15 of 31 terms, and 9 of 9 predictors
Termination condition: Reached nk 31
Importance: temp, ibt, humidity, doy, dpg, vis, wind, ibh, vh
Number of terms at each degree of interaction: 1 5 9
GCV 13.22659    RSS 3464.405    GRSq 0.7945405    RSq 0.83593
> printh(earth(O3 ~ ., data=ozone1, degree=2, nk = 31, fast.k = 5, fast.beta = 1))
===earth(O3 ~ ., data = ozone1, degree = 2, nk = 31, fast.k = 5,     fast.beta = 1) 
Selected 11 of 17 terms, and 7 of 9 predictors
Termination condition: RSq changed by less than 0.001 at 17 terms
Importance: humidity, ibt, doy, temp, dpg, ibh, wind, vh-unused, ...
Number of terms at each degree of interaction: 1 8 2
GCV 14.15189    RSS 3963.216    GRSq 0.780167    RSq 0.8123069
> printh(earth(O3 ~ ., data=ozone1, degree=2, nk = 31, fast.k = 5, fast.beta = 0))
===earth(O3 ~ ., data = ozone1, degree = 2, nk = 31, fast.k = 5,     fast.beta = 0) 
Selected 11 of 17 terms, and 6 of 9 predictors
Termination condition: RSq changed by less than 0.001 at 17 terms
Importance: humidity, ibt, doy, ibh, vis, dpg, temp-unused, vh-unused, ...
Number of terms at each degree of interaction: 1 6 4
GCV 13.89191    RSS 3890.408    GRSq 0.7842055    RSq 0.815755
> 
> cat("--- plot.earth and plot.earth.models ------------\n")
--- plot.earth and plot.earth.models ------------
> 
> a <- earth(O3 ~ ., data=ozone1) # formula interface
> 
> if (PLOT)
+     plot(a, caption="plot.earth test 1", col.rsq=3, smooth.col=4, qqline.col="pink",
+          col.vline=1, col.npreds=0, nresiduals=100, cum.grid="grid",
+          grid.col="lightblue", col.sel.grid="lightgreen")
> 
> set.seed(1)
> if (PLOT) {
+     plot(a, caption="plot.earth test 2", which=c(3,4,1), ylim=c(.2,.9),
+          id.n=20, legend.pos=c(10,.6), pch=20, lty.vline=1, cex.legend=1,
+          grid.col="lightblue")
+ 
+     plot(a, caption="plot.earth test 3", which=2, main="test main")
+ }
> 
> a1 <- earth(ozone1[,c(2:4,10)], ozone1[,1])     # x,y interface
> 
> if (PLOT) {
+     plot(a, caption="plot.earth test 4", id.n=1)
+     set.seed(1)
+     plot.earth.models(a, which=1, ylim=c(.4,.8), jitter=.01)
+ 
+     plot.earth.models(a1)
+ 
+     plot.earth.models(list(a, a1), col.cum=c(3,4),  col.grsq=c(1,2), col.rsq=c(3,4),
+          col.npreds=1, col.vline=1, lty.vline=3,
+          legend.pos=c(5,.4), legend.text=c("a", "b", "c"), cex.legend=1.3)
+ }
> 
> cat("--- plot.earth args -----------------------------\n")
--- plot.earth args -----------------------------
> 
> test.plot.earth.args <- function()
+ {
+     caption <- "test earth args"
+     printh(caption)
+ 
+     argtest <- earth(ozone1[,c(2:4,10)], ozone1[,1])
+ 
+     old.par <- par(no.readonly=TRUE)
+     on.exit(par(old.par))
+     par(mfrow=c(2,3))
+     par(cex = 0.8)
+     par(mar = c(3, 3, 3, 0.5)) # small margins and text to pack figs in
+     par(mgp = c(1.6, 0.6, 0))  # flatten axis elements
+     oma <- par("oma") # make space for caption
+     oma[3] <- 2.4
+     par(oma=oma)
+     par(cex.main=1)
+ 
+     plot(argtest, do.par=FALSE, which=1,
+          main="default")
+ 
+     mtext(caption, outer=TRUE, font=2)
+ 
+     plot(argtest, do.par=FALSE, which=1,
+          col.rsq=3, col.grsq=2,
+          col.npreds="blue", grid.col="lightblue",
+          main=sprint("%s\n%s",
+             "col.rsq=3, col.grsq=2, ",
+             "col.npreds=\"lightblue\", col.sel.grid=\"gray\""))
+ 
+     plot(argtest, do.par=FALSE, which=1,
+          col.vline="pink", legend.pos="topleft",
+          lty.grsq=2, lty.npreds=1, lty.vline=1,
+          main=sprint("%s\n%s",
+             "col.vline=\"pink\", legend.pos=\"topleft\", ",
+             "lty.grsq=2, lty.npreds=1, lty.vline=1"))
+ 
+     plot(argtest, do.par=FALSE, which=1,
+          legend.pos=NA, col.npreds=0,
+          main="legend.pos=NA, col.npreds=0")
+ 
+     plot(argtest, do.par=FALSE, which=1,
+          legend.pos=0,
+          main="legend.pos=0")
+ }
> test.plot.earth.args()
===caption [1] "test earth args"
> par(org.par)
> 
> cat("--- test minspan --------------------------------\n")
--- test minspan --------------------------------
> 
> a.minspan2 <- earth(O3 ~ ., data=ozone1, minspan=2)
> printh(summary(a.minspan2))
===summary(a.minspan2) 
Call: earth(formula=O3~., data=ozone1, minspan=2)

               coefficients
(Intercept)       37.206815
h(5740-vh)        -0.020094
h(54-humidity)    -0.130146
h(temp-58)         0.322610
h(1046-ibh)       -0.003655
h(dpg-12)         -0.092232
h(ibt-120)         0.038616
h(vis-17)         -0.372533
h(80-vis)         -0.319300
h(vis-80)          0.365130
h(89-doy)         -0.144947
h(doy-159)        -0.032265

Selected 12 of 19 terms, and 8 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, vh, humidity, dpg, doy, ibh, vis, ibt, wind-unused
Number of terms at each degree of interaction: 1 11 (additive model)
GCV 14.47406    RSS 4133.834    GRSq 0.7751625    RSq 0.8042266
> 
> a.minspan0 <- earth(O3 ~ ., data=ozone1, minspan=0)
> printh(summary(a.minspan0))
===summary(a.minspan0) 
Call: earth(formula=O3~., data=ozone1, minspan=0)

               coefficients
(Intercept)      14.1595171
h(5860-vh)       -0.0137728
h(wind-3)        -0.3377222
h(54-humidity)   -0.1349547
h(temp-58)        0.2791320
h(1105-ibh)      -0.0033837
h(dpg-10)        -0.0991581
h(ibt-120)        0.0326330
h(150-vis)        0.0231881
h(96-doy)        -0.1105145
h(doy-96)         0.0406468
h(doy-158)       -0.0836732

Selected 12 of 20 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, dpg, doy, vh, ibh, vis, ibt, wind
Number of terms at each degree of interaction: 1 11 (additive model)
GCV 14.61004    RSS 4172.671    GRSq 0.7730502    RSq 0.8023874
> 
> a.minspan.minus1 <- earth(O3 ~ ., data=ozone1, minspan=-1)
> printh(summary(a.minspan.minus1))
===summary(a.minspan.minus1) 
Call: earth(formula=O3~., data=ozone1, minspan=-1)

               coefficients
(Intercept)      14.8317540
ibh               0.0035879
h(5760-vh)       -0.0131360
h(64-humidity)   -0.0630395
h(temp-62)        0.3670405
h(ibh-823)       -0.0043888
h(dpg-24)        -0.1188100
h(120-vis)        0.0359176
h(206-doy)       -0.0486385
h(doy-206)       -0.0585411

Selected 10 of 19 terms, and 7 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, ibh, humidity, dpg, vis, doy, vh, wind-unused, ...
Number of terms at each degree of interaction: 1 9 (additive model)
GCV 16.16163    RSS 4736.877    GRSq 0.748948    RSq 0.7756673
> 
> a.minspan.minus3 <- earth(O3 ~ ., data=ozone1, minspan=-3)
> printh(summary(a.minspan.minus3))
===summary(a.minspan.minus3) 
Call: earth(formula=O3~., data=ozone1, minspan=-3)

               coefficients
(Intercept)      13.5336798
h(5690-vh)       -0.0169026
h(vh-5690)        0.0155040
h(wind-3)        -0.2790195
h(64-humidity)   -0.0997117
h(temp-62)        0.5474683
h(temp-72)       -0.3244650
h(dpg-24)        -0.1084691
h(ibt-107)        0.0171885
h(150-vis)        0.0232805
h(119-doy)       -0.1064486
h(doy-119)       -0.0334354

Selected 12 of 20 terms, and 8 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, dpg, vis, doy, vh, humidity, ibh-unused, wind, ibt
Number of terms at each degree of interaction: 1 11 (additive model)
GCV 14.82868    RSS 4235.117    GRSq 0.7696538    RSq 0.79943
> 
> a.endspan80 <- earth(O3 ~ ., data=ozone1, endspan=80)
> printh(summary(a.endspan80))
===summary(a.endspan80) 
Call: earth(formula=O3~., data=ozone1, endspan=80)

               coefficients
(Intercept)      14.7832332
h(5770-vh)       -0.0160418
h(wind-3)        -0.3028539
h(55-humidity)   -0.1303358
h(temp-58)        0.3179697
h(1046-ibh)      -0.0041830
h(dpg-10)        -0.0933000
h(ibt-121)        0.0371643
h(150-vis)        0.0223985
h(118-doy)       -0.0989561
h(doy-147)       -0.0367509

Selected 11 of 20 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, doy, humidity, dpg, ibh, vh, vis, ibt, wind
Number of terms at each degree of interaction: 1 10 (additive model)
GCV 14.31885    RSS 4142.964    GRSq 0.7775735    RSq 0.8037943
> 
> cat("--- test multiple responses ---------------------\n")
--- test multiple responses ---------------------
> 
> # this uses the global matrix data.global (data.global[,1:2] is the response)
> 
> test.two.responses <- function(itest, func1, func2,
+     degree=2, nk=51, plotit=PLOT, test.rsq=TRUE, trace=0, minspan=0,
+     test.mars.to.earth=FALSE, pmethod="backward")
+ {
+     if(typeof(func1) == "character")
+         funcnames <- paste("multiple responses", func1, func2)
+     else
+         funcnames <- paste("multiple responses", deparse(substitute(func1)), deparse(substitute(func2)))
+     cat("itest", sprint("%-3d", itest), funcnames,
+         " degree", sprint("%-2d", degree), "nk", sprint("%-3g", nk), "\n\n")
+     gc()
+     fite <- earth(x=data.global[,c(-1,-2), drop=FALSE], y=data.global[,1:2],
+                 degree=degree, trace=trace, nk=nk, pmethod=pmethod, minspan=minspan)
+     printh(fite)
+     caption <- paste("itest ", itest, ": ", funcnames, " degree=", degree, " nk=", nk, sep="")
+     if(plotit) {
+         if(typeof(func1) == "character") {
+             plotmo(fite, caption=caption, nresponse=1, trace=-1)
+             plotmo(fite, nresponse=2, trace=-1)
+         } else {
+             plotmo(fite, func=func1, caption=caption, nresponse=1)
+             plotmo(fite, func=func2, nresponse=2)
+         }
+         plot(fite, caption=caption, nresponse=1)
+         plot(fite, nresponse=2)
+     }
+     cat("\n")
+     if(test.mars.to.earth) {
+         cat("Testing mars.to.earth with a multiple response model\n")
+         fitm <- mars(data.global[,c(-1,-2), drop=FALSE], data.global[,1:2],
+                      degree=degree, trace=(trace!=0), nk=nk)
+         fitme <- mars.to.earth(fitm)
+         printh(fitme)
+         printh(summary(fitme))
+         if(plotit) {
+             plotmo(fitm, func=func1, caption=caption, nresponse=1, clip=FALSE)
+             plotmo(fitm, func=func2, nresponse=2, clip=FALSE)
+         }
+ # TODO following code causes error "nk" not found, looking in wrong environment?
+ #       cat("Expect warnings because of weights in the mars model\n")
+ #       fitm <- mars(data.global[,c(-1,-2), drop=FALSE], data.global[,1:2],
+ #                    degree=degree, trace=(trace!=0), nk=nk, wp=c(1,2))
+ #       fitme <- mars.to.earth(fitm)
+ #       printh(fitme)
+ #       printh(summary(fitme))
+     }
+     fite
+ }
> 
> N <- 100
> set.seed(1)
> x1 <- runif(N, -1, 1)
> x2 <- runif(N, -1, 1)
> x3 <- runif(N, -1, 1)
> x4 <- runif(N, -1, 1)
> x5 <- runif(N, -1, 1)
> 
> func1 <- function(x)
+ {
+     sin(3 * x[,1]) + x[,2]
+ }
> func7 <- function(x)    # just one predictor
+ {
+     sin(5 * x[,1])
+ }
> x.global <- cbind(                                     x1, x2)
> data.global <- cbind(func1(x.global), func7(x.global), x1, x2)
> colnames(data.global) = c("func1", "func7", "x1", "x2")
> # expect pmethod="ex" cannot be used with multiple response models
> expect.err(try(test.two.responses(itest, func1, func7, nk=51, degree=1, pmethod="ex")), "not allowed with multiple response models")
itest 5   multiple responses func1 func7  degree 1  nk 51  

Error : pmethod="exhaustive" is not allowed with multiple response models
       (y has 2 columns, use trace=4 to see y)
Got expected error from try(test.two.responses(itest, func1, func7, nk = 51, degree = 1,     pmethod = "ex"))
> # expect pmethod="seq" cannot be used with multiple response models
> expect.err(try(test.two.responses(itest, func1, func7, nk=51, degree=1, pmethod="seq")), "not allowed with multiple response models")
itest 5   multiple responses func1 func7  degree 1  nk 51  

Error : pmethod="seqrep" is not allowed with multiple response models
       (y has 2 columns, use trace=4 to see y)
Got expected error from try(test.two.responses(itest, func1, func7, nk = 51, degree = 1,     pmethod = "seq"))
> itest <- itest+1; a <- test.two.responses(itest, func1, func7, nk=51, degree=1)
itest 6   multiple responses func1 func7  degree 1  nk 51  

===fite 
Selected 9 of 9 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 9 terms
Importance: x1, x2
Number of terms at each degree of interaction: 1 8 (additive model)

              GCV       RSS      GRSq       RSq
func1 0.002626520 0.1809409 0.9969000 0.9978211
func7 0.007889046 0.5434764 0.9846251 0.9891931
All   0.010515566 0.7244173 0.9922701 0.9945668
 plotmo grid:    x1         x2
        -0.02437858 0.03719751
 plotmo grid:    x1         x2
        -0.02437858 0.03719751

> printh(summary(a))
===summary(a) 
Call: earth(x=data.global[,c(-1,-2),drop=FALSE], y=data.global[,1:2],
            pmethod=pmethod, trace=trace, degree=degree, nk=nk,
            minspan=minspan)

                      func1      func7
(Intercept)      -1.4159357 -0.6824246
h(-0.468983-x1)   1.4219106  3.9942993
h(x1- -0.468983)  1.8463556 -1.4788784
h(x1- -0.235224)  0.9882662  5.9409061
h(x1-0.209867)   -0.8510911 -4.4376027
h(x1-0.425029)   -2.5321006 -4.8071373
h(x1-0.739382)   -2.1198279  2.4557576
h(-0.329025-x2)  -1.0346040 -0.0308457
h(x2- -0.329025)  0.9870580 -0.0232994

Selected 9 of 9 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 9 terms
Importance: x1, x2
Number of terms at each degree of interaction: 1 8 (additive model)

              GCV       RSS      GRSq       RSq
func1 0.002626520 0.1809409 0.9969000 0.9978211
func7 0.007889046 0.5434764 0.9846251 0.9891931
All   0.010515566 0.7244173 0.9922701 0.9945668
> printh(summary(a, style="bf"))
===summary(a, style = "bf") 
Call: earth(x=data.global[,c(-1,-2),drop=FALSE], y=data.global[,1:2],
            pmethod=pmethod, trace=trace, degree=degree, nk=nk,
            minspan=minspan)

func1 =
  -1.415936
  +  1.421911 * bf1
  +  1.846356 * bf2
  + 0.9882662 * bf3
  - 0.8510911 * bf4
  -  2.532101 * bf5
  -  2.119828 * bf6
  -  1.034604 * bf7
  +  0.987058 * bf8

   bf1  h(-0.468983-x1)
   bf2  h(x1--0.468983)
   bf3  h(x1--0.235224)
   bf4  h(x1-0.209867)
   bf5  h(x1-0.425029)
   bf6  h(x1-0.739382)
   bf7  h(-0.329025-x2)
   bf8  h(x2--0.329025)

func7 =
  -0.6824246
  +   3.994299 * bf1
  -   1.478878 * bf2
  +   5.940906 * bf3
  -   4.437603 * bf4
  -   4.807137 * bf5
  +   2.455758 * bf6
  - 0.03084575 * bf7
  - 0.02329942 * bf8

   bf1  h(-0.468983-x1)
   bf2  h(x1--0.468983)
   bf3  h(x1--0.235224)
   bf4  h(x1-0.209867)
   bf5  h(x1-0.425029)
   bf6  h(x1-0.739382)
   bf7  h(-0.329025-x2)
   bf8  h(x2--0.329025)

Selected 9 of 9 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 9 terms
Importance: x1, x2
Number of terms at each degree of interaction: 1 8 (additive model)

              GCV       RSS      GRSq       RSq
func1 0.002626520 0.1809409 0.9969000 0.9978211
func7 0.007889046 0.5434764 0.9846251 0.9891931
All   0.010515566 0.7244173 0.9922701 0.9945668
> if (PLOT) {
+     plotmo(a, nresponse=1, trace=-1)     # test generation of caption based on response name
+     plotmo(a, nresponse=2, trace=-1)
+     plot(a, nresponse=1)
+     plot(a, nresponse=2)
+ }
> x.global <- cbind(                                     x1, x2)
> data.global <- cbind(func1(x.global), func7(x.global), x1, x2)
> colnames(data.global) = c("func1",
+    "a.very.long.in.fact.extremely.long.response.name",
+    "x1.a.very.long.in.fact.extremely.long.predictor.name",
+    "x2")
> itest <- itest+1; a <- test.two.responses(itest, func1, func7, nk=51, degree=3)
itest 7   multiple responses func1 func7  degree 3  nk 51  

===fite 
Selected 9 of 9 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 9 terms
Importance: x1.a.very.long.in.fact.extremely.long.predictor.name, x2
Number of terms at each degree of interaction: 1 8 (additive model)

                                                         GCV       RSS
func1                                            0.002899230 0.1809409
a.very.long.in.fact.extremely.long.response.name 0.008708162 0.5434764
All                                              0.011607392 0.7244173
                                                      GRSq       RSq
func1                                            0.9965782 0.9978211
a.very.long.in.fact.extremely.long.response.name 0.9830287 0.9891931
All                                              0.9914675 0.9945668
 plotmo grid:    x1.a.very.long.in.fact.extremely.long.predictor.name
                                                          -0.02437858
         x2
 0.03719751
 plotmo grid:    x1.a.very.long.in.fact.extremely.long.predictor.name
                                                          -0.02437858
         x2
 0.03719751

> printh(summary(a))
===summary(a) 
Call: earth(x=data.global[,c(-1,-2),drop=FALSE], y=data.global[,1:2],
            pmethod=pmethod, trace=trace, degree=degree, nk=nk,
            minspan=minspan)

                                                                        func1
(Intercept)                                                        -1.4159357
h(-0.468983-x1.a.very.long.in.fact.extremely.long.predictor.name)   1.4219106
h(x1.a.very.long.in.fact.extremely.long.predictor.name- -0.468983)  1.8463556
h(x1.a.very.long.in.fact.extremely.long.predictor.name- -0.235224)  0.9882662
h(x1.a.very.long.in.fact.extremely.long.predictor.name-0.209867)   -0.8510911
h(x1.a.very.long.in.fact.extremely.long.predictor.name-0.425029)   -2.5321006
h(x1.a.very.long.in.fact.extremely.long.predictor.name-0.739382)   -2.1198279
h(-0.329025-x2)                                                    -1.0346040
h(x2- -0.329025)                                                    0.9870580
                                                                   a.very.long.in.fact.extremely.long.response.name
(Intercept)                                                                                              -0.6824246
h(-0.468983-x1.a.very.long.in.fact.extremely.long.predictor.name)                                         3.9942993
h(x1.a.very.long.in.fact.extremely.long.predictor.name- -0.468983)                                       -1.4788784
h(x1.a.very.long.in.fact.extremely.long.predictor.name- -0.235224)                                        5.9409061
h(x1.a.very.long.in.fact.extremely.long.predictor.name-0.209867)                                         -4.4376027
h(x1.a.very.long.in.fact.extremely.long.predictor.name-0.425029)                                         -4.8071373
h(x1.a.very.long.in.fact.extremely.long.predictor.name-0.739382)                                          2.4557576
h(-0.329025-x2)                                                                                          -0.0308457
h(x2- -0.329025)                                                                                         -0.0232994

Selected 9 of 9 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 9 terms
Importance: x1.a.very.long.in.fact.extremely.long.predictor.name, x2
Number of terms at each degree of interaction: 1 8 (additive model)

                                                         GCV       RSS
func1                                            0.002899230 0.1809409
a.very.long.in.fact.extremely.long.response.name 0.008708162 0.5434764
All                                              0.011607392 0.7244173
                                                      GRSq       RSq
func1                                            0.9965782 0.9978211
a.very.long.in.fact.extremely.long.response.name 0.9830287 0.9891931
All                                              0.9914675 0.9945668
> print(evimp(a))
                                                     nsubsets   gcv    rss
x1.a.very.long.in.fact.extremely.long.predictor.name        8 100.0  100.0
x2                                                          6  65.6   62.4
> print.default(evimp(a))
                                                     col used nsubsets
x1.a.very.long.in.fact.extremely.long.predictor.name   1    1        8
x2                                                     2    1        6
                                                           gcv gcv.match
x1.a.very.long.in.fact.extremely.long.predictor.name 100.00000         1
x2                                                    65.60412         1
                                                           rss rss.match
x1.a.very.long.in.fact.extremely.long.predictor.name 100.00000         1
x2                                                    62.37599         1
attr(,"class")
[1] "evimp"
attr(,"sqrt")
[1] TRUE
> 
> eqn56 <- function(x) # Friedman MARS paper equation 56
+ {
+     0.1 * exp(4*x[,1]) +
+     4 / (1 + exp(-20*(x[,2]-0.5))) +
+     3 * x[,3] +
+     2 * x[,4] +
+     x[,5]
+ }
> neg.eqn56 <- function(x)
+ {
+     -eqn56(x)
+ }
> 
> eqn56noise <- function(x)
+ {
+     set.seed(ncol(x))
+     eqn56(x) + rnorm(nrow(x),0,1)
+ }
> 
> neg.eqn56noise <- function(x)
+ {
+     -eqn56noise(x)
+ }
> 
> robot.arm <- function(x) # Friedman Fast MARS paper
+ {
+     l1     <- x[,1]
+     l2     <- x[,2]
+     theta1 <- x[,3]
+     theta2 <- x[,4]
+     phi    <- x[,5]
+ 
+     x1 <- l1 * cos(theta1) - l2 * cos(theta1 + theta2) * cos(phi)
+     y <-  l1 * sin(theta1) - l2 * sin(theta1 + theta2) * cos(phi)
+     z <-  l2 *  sin(theta2) * sin(phi)
+ 
+     sqrt(x1^2 + y^2 + z^2)
+ }
> x.global <- cbind(                                           x1, x2, x3, x4, x5)
> data.global <- cbind(eqn56=eqn56(x.global), neg.eqn56noise(x.global), x1, x2, x3, x4, x5)
> colnames(data.global) = c("", "neg.eqn56noise", "x1", "x2", "x3", "x4", "x5")
> itest <- itest+1; a <- test.two.responses(itest, eqn56, neg.eqn56noise, nk=51, degree=1)
itest 8   multiple responses eqn56 neg.eqn56noise  degree 1  nk 51  

===fite 
Selected 12 of 22 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 22 terms
Importance: x3, x2, x4, x1, x5
Number of terms at each degree of interaction: 1 11 (additive model)

                            GCV       RSS      GRSq       RSq
data.global[, 1:2][1] 0.1186568  7.035159 0.9859153 0.9914796
neg.eqn56noise        1.0576805 62.709877 0.8846994 0.9302502
All                   1.1763373 69.745036 0.9331542 0.9595624
 plotmo grid:    x1         x2         x3          x4          x5
        -0.02437858 0.03719751 -0.2437968 -0.07448578 -0.04164241
 plotmo grid:    x1         x2         x3          x4          x5
        -0.02437858 0.03719751 -0.2437968 -0.07448578 -0.04164241

> print(evimp(a))
   nsubsets   gcv    rss
x3       11 100.0  100.0
x2       10  82.5   81.2
x4        9  59.0   57.8
x1        8  48.0   46.6
x5        6  33.7   32.2
> print.default(evimp(a))
   col used nsubsets       gcv gcv.match       rss rss.match
x3   3    1       11 100.00000         1 100.00000         1
x2   2    1       10  82.46294         1  81.21481         1
x4   4    1        9  58.98392         1  57.75405         1
x1   1    1        8  47.99407         1  46.58408         1
x5   5    1        6  33.69458         1  32.15406         1
attr(,"class")
[1] "evimp"
attr(,"sqrt")
[1] TRUE
> 
> x.global <- cbind(                                           x1, x2, x3, x4, x5)
> data.global <- cbind(eqn56=eqn56(x.global), neg.eqn56noise(x.global), x1, x2, x3, x4, x5)
> colnames(data.global) = NULL
> itest <- itest+1; a70 <- test.two.responses(itest, eqn56, neg.eqn56noise, nk=51, degree=2)
itest 9   multiple responses eqn56 neg.eqn56noise  degree 2  nk 51  

===fite 
Selected 11 of 36 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 36 terms
Importance: x3, x2, x4, x1, x5
Number of terms at each degree of interaction: 1 10 (additive model)

                            GCV       RSS      GRSq       RSq
data.global[, 1:2][1] 0.1491246  8.166063 0.9822988 0.9901100
data.global[, 1:2][2] 1.2644713 69.242451 0.8621565 0.9229843
All                   1.4135959 77.408514 0.9196719 0.9551192
 plotmo grid:    x1         x2         x3          x4          x5
        -0.02437858 0.03719751 -0.2437968 -0.07448578 -0.04164241
 plotmo grid:    x1         x2         x3          x4          x5
        -0.02437858 0.03719751 -0.2437968 -0.07448578 -0.04164241

> printh(summary(a70))
===summary(a70) 
Call: earth(x=data.global[,c(-1,-2),drop=FALSE], y=data.global[,1:2],
            pmethod=pmethod, trace=trace, degree=degree, nk=nk,
            minspan=minspan)

                 data.global[, 1:2][1] data.global[, 1:2][2]
(Intercept)                  0.2818910             -0.199523
h(0.565866-x1)              -0.5573832              0.701461
h(x1-0.565866)               8.6735609             -6.756016
h(x2-0.266987)               5.6617262             -3.485078
h(x2-0.458619)              24.7167189            -41.977152
h(x2-0.516206)             -26.6087010             42.046569
h(x3-0.109801)               2.5861859             -2.829496
h(0.26284-x3)               -2.9626317              2.501109
h(-0.303396-x4)             -3.1086768              3.484234
h(x4-0.124354)               2.6383691             -2.972662
h(x5- -0.859935)             0.9423879             -0.854188

Selected 11 of 36 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 36 terms
Importance: x3, x2, x4, x1, x5
Number of terms at each degree of interaction: 1 10 (additive model)

                            GCV       RSS      GRSq       RSq
data.global[, 1:2][1] 0.1491246  8.166063 0.9822988 0.9901100
data.global[, 1:2][2] 1.2644713 69.242451 0.8621565 0.9229843
All                   1.4135959 77.408514 0.9196719 0.9551192
> printh(summary(a70, style="bf"))
===summary(a70, style = "bf") 
Call: earth(x=data.global[,c(-1,-2),drop=FALSE], y=data.global[,1:2],
            pmethod=pmethod, trace=trace, degree=degree, nk=nk,
            minspan=minspan)

data.global[, 1:2][1] =
  0.281891
  -  0.5573832 * bf1
  +   8.673561 * bf2
  +   5.661726 * bf3
  +   24.71672 * bf4
  -    26.6087 * bf5
  +   2.586186 * bf6
  -   2.962632 * bf7
  -   3.108677 * bf8
  +   2.638369 * bf9
  +  0.9423879 * bf10

   bf1  h(0.565866-x1)
   bf2  h(x1-0.565866)
   bf3  h(x2-0.266987)
   bf4  h(x2-0.458619)
   bf5  h(x2-0.516206)
   bf6  h(x3-0.109801)
   bf7  h(0.26284-x3)
   bf8  h(-0.303396-x4)
   bf9  h(x4-0.124354)
  bf10  h(x5--0.859935)

data.global[, 1:2][2] =
  -0.1995226
  +  0.7014611 * bf1
  -   6.756016 * bf2
  -   3.485078 * bf3
  -   41.97715 * bf4
  +   42.04657 * bf5
  -   2.829496 * bf6
  +   2.501109 * bf7
  +   3.484234 * bf8
  -   2.972662 * bf9
  -  0.8541879 * bf10

   bf1  h(0.565866-x1)
   bf2  h(x1-0.565866)
   bf3  h(x2-0.266987)
   bf4  h(x2-0.458619)
   bf5  h(x2-0.516206)
   bf6  h(x3-0.109801)
   bf7  h(0.26284-x3)
   bf8  h(-0.303396-x4)
   bf9  h(x4-0.124354)
  bf10  h(x5--0.859935)

Selected 11 of 36 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 36 terms
Importance: x3, x2, x4, x1, x5
Number of terms at each degree of interaction: 1 10 (additive model)

                            GCV       RSS      GRSq       RSq
data.global[, 1:2][1] 0.1491246  8.166063 0.9822988 0.9901100
data.global[, 1:2][2] 1.2644713 69.242451 0.8621565 0.9229843
All                   1.4135959 77.408514 0.9196719 0.9551192
> 
> N1 <- 100
> set.seed(1)
> x1. <- runif(N1, -1, 1)
> x2. <- runif(N1, -1, 1)
> x3. <- runif(N1, -1, 1)
> x4. <- runif(N1, -1, 1)
> x5. <- runif(N1, -1, 1)
> 
> x.global <- cbind(                                        (x1.+1)/2, (x2.+2)/2, pi*(x3.+1), pi*(x4.+1), pi*x5./2 )
> data.global <- cbind(robot.arm(x.global), eqn56(x.global), (x1.+1)/2, (x2.+2)/2, pi*(x3.+1), pi*(x4.+1), pi*x5./2 )
> colnames(x.global)    <- c(                "l1", "l2", "theta1", "theta2", "phi")
> colnames(data.global) <- c("arm", "eqn56", "l1", "l2", "theta1", "theta2", "phi")
> itest <- itest+1; test.two.responses(itest, robot.arm, eqn56, nk=51, degree=1)
itest 10  multiple responses robot.arm eqn56  degree 1  nk 51  

===fite 
Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.06212730 3.877365 0.6674660 0.7882518
eqn56 0.04559835 2.845793 0.9990475 0.9993935
All   0.10772566 6.723158 0.9977586 0.9985727
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174

Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.06212730 3.877365 0.6674660 0.7882518
eqn56 0.04559835 2.845793 0.9990475 0.9993935
All   0.10772566 6.723158 0.9977586 0.9985727
> itest <- itest+1; test.two.responses(itest, robot.arm, eqn56, nk=51, degree=2, test.mars.to.earth=TRUE)
itest 11  multiple responses robot.arm eqn56  degree 2  nk 51  

===fite 
Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.07080652 3.877365 0.6210109 0.7882518
eqn56 0.05196847 2.845793 0.9989145 0.9993935
All   0.12277499 6.723158 0.9974454 0.9985727
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174

Testing mars.to.earth with a multiple response model
Converted mars(x=data.global[,c(-1,-2),drop=FALSE], y=data.global[,1:2],
               degree=degree, nk=nk, trace.mars=(trace!=0))

to earth(x=data.global[,c(-1,-2),drop=FALSE], y=data.global[,1:2],
                degree=degree, nk=nk)

===fitme 
Selected 14 of 14 terms, and 5 of 5 predictors
Termination condition: Unknown
Importance: object has no prune.terms, call update() on the model to fix that
Number of terms at each degree of interaction: 1 11 2

             GCV      RSS      GRSq       RSq
arm   0.06354264 2.810014 0.6598905 0.8465412
eqn56 0.02822229 1.248060 0.9994105 0.9997340
All   0.09176492 4.058074 0.9997770 0.9998994
===summary(fitme) 
Call: earth(x=data.global[,c(-1,-2),drop=FALSE], y=data.global[,1:2],
            degree=degree, nk=nk)

                                          arm      eqn56
(Intercept)                        1.21455366 17.9497354
h(l1-0.48208)                      0.74838045  3.1350878
h(0.712515-l1)                    -0.29309259 -1.2345462
h(l1-0.712515)                     0.45693753  8.6324286
h(0.689194-l2)                    -0.56638468 -6.5226645
h(l2-0.689194)                     0.80658229  0.0048442
h(2.05469-theta1)                  0.04949653 -2.9820177
h(theta1-2.05469)                  0.01153761  3.0259557
h(3.53226-theta2)                 -0.14968401 -1.9869680
h(theta2-3.53226)                 -0.26441106  2.0236977
h(-0.0748075-phi)                 -0.14373035 -0.9622197
h(phi- -0.0748075)                -0.22638721  0.9964946
h(0.48208-l1)                     -0.18021728 -0.0612455
h(l1-0.48208) * h(theta2-1.51306) -2.04353916 -0.4060211

Selected 14 of 14 terms, and 5 of 5 predictors
Termination condition: Unknown
Importance: object has no prune.terms, call update() on the model to fix that
Number of terms at each degree of interaction: 1 11 2

             GCV      RSS      GRSq       RSq
arm   0.06354264 2.810014 0.6598905 0.8465412
eqn56 0.02822229 1.248060 0.9994105 0.9997340
All   0.09176492 4.058074 0.9997770 0.9998994
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174
Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.07080652 3.877365 0.6210109 0.7882518
eqn56 0.05196847 2.845793 0.9989145 0.9993935
All   0.12277499 6.723158 0.9974454 0.9985727
> itest <- itest+1; test.two.responses(itest, robot.arm, eqn56, nk=201, degree=1)
itest 12  multiple responses robot.arm eqn56  degree 1  nk 201 

===fite 
Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.06212730 3.877365 0.6674660 0.7882518
eqn56 0.04559835 2.845793 0.9990475 0.9993935
All   0.10772566 6.723158 0.9977586 0.9985727
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174

Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.06212730 3.877365 0.6674660 0.7882518
eqn56 0.04559835 2.845793 0.9990475 0.9993935
All   0.10772566 6.723158 0.9977586 0.9985727
> itest <- itest+1; test.two.responses(itest, robot.arm, eqn56, nk=201, degree=2)
itest 13  multiple responses robot.arm eqn56  degree 2  nk 201 

===fite 
Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.07080652 3.877365 0.6210109 0.7882518
eqn56 0.05196847 2.845793 0.9989145 0.9993935
All   0.12277499 6.723158 0.9974454 0.9985727
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174

Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.07080652 3.877365 0.6210109 0.7882518
eqn56 0.05196847 2.845793 0.9989145 0.9993935
All   0.12277499 6.723158 0.9974454 0.9985727
> itest <- itest+1; test.two.responses(itest, robot.arm, eqn56, nk=201, degree=10)
itest 14  multiple responses robot.arm eqn56  degree 10 nk 201 

===fite 
Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.07080652 3.877365 0.6210109 0.7882518
eqn56 0.05196847 2.845793 0.9989145 0.9993935
All   0.12277499 6.723158 0.9974454 0.9985727
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174
 plotmo grid:    l1       l2   theta1   theta2         phi
          0.4878107 1.018599 2.375682 2.907589 -0.06541174

Selected 11 of 11 terms, and 5 of 5 predictors
Termination condition: RSq changed by less than 0.001 at 11 terms
Importance: theta1, theta2, l1, phi, l2
Number of terms at each degree of interaction: 1 10 (additive model)

             GCV      RSS      GRSq       RSq
arm   0.07080652 3.877365 0.6210109 0.7882518
eqn56 0.05196847 2.845793 0.9989145 0.9993935
All   0.12277499 6.723158 0.9974454 0.9985727
> 
> attach(ozone1)
> x.global <- cbind(                wind, humidity, temp, ibh, dpg, ibt, vis)
> data.global <- cbind(O3, doy, vh, wind, humidity, temp, ibh, dpg, ibt, vis)
> itest <- itest+1; test.two.responses(itest, "O3", "doy", nk=51, degree=2)
itest 15  multiple responses O3 doy  degree 2  nk 51  

===fite 
Selected 13 of 47 terms, and 8 of 8 predictors
Termination condition: Reached nk 51
Importance: wind, vh, ibh, temp, dpg, vis, humidity, ibt
Number of terms at each degree of interaction: 1 5 7

          GCV        RSS      GRSq       RSq
O3    22.9046    6205.13 0.6442040 0.7061325
doy 6853.8813 1856799.52 0.3727883 0.4819583
All 6876.7859 1863004.66 0.3743779 0.4832712

Selected 13 of 47 terms, and 8 of 8 predictors
Termination condition: Reached nk 51
Importance: wind, vh, ibh, temp, dpg, vis, humidity, ibt
Number of terms at each degree of interaction: 1 5 7

          GCV        RSS      GRSq       RSq
O3    22.9046    6205.13 0.6442040 0.7061325
doy 6853.8813 1856799.52 0.3727883 0.4819583
All 6876.7859 1863004.66 0.3743779 0.4832712
> detach(ozone1)
> 
> cat("--- formula based multiple response -------------\n")
--- formula based multiple response -------------
> 
> a2 <- earth(cbind(O3,doy) ~ ., data=ozone1, degree=2)
> if (PLOT) {
+     plotmo(a2, nresponse=1, trace=-1)                  # TODO1 delete
+     plotmo(a2, nresponse=1, trace=-1) # test generation of caption based on response name
+     plotmo(a2, nresponse=2, trace=-1)
+     plot(a2, nresponse=1) # TODO delete
+     plot(a2, nresponse=1)
+     plot(a2, nresponse=2)
+ }
> 
> cat("--- test plot.earth.models with multiple responses ---\n")
--- test plot.earth.models with multiple responses ---
> 
> set.seed(1)
> a <- earth(O3 ~ ., data=ozone1, degree=2)
> a2 <- earth(cbind(O3,doy) ~ ., data=ozone1, degree=2)
> b2 <- earth(cbind(O3,doy) ~ ., data=ozone1, degree=1)
> if (PLOT) {
+     plot.earth.models(list(a, a2), caption="plot.earth.models with multiple responses, list(a,a2)")
+     plot.earth.models(list(a2, a), caption="plot.earth.models with multiple responses, list(a2,a)",
+                       col.rsq=c(2,3), col.npreds=c(2,3))
+     plot.earth.models(list(a2, b2), caption="plot.earth.models with multiple responses, list(a2,b2)",
+                       col.rsq=c(2,3), col.npreds=c(4,5), jitter=.01, legend.pos="topleft")
+ }
> 
> cat("--- subset --------------------------------------\n")
--- subset --------------------------------------
> 
> set.seed(9)
> train.subset <- sample(1:nrow(ozone1), .8 * nrow(ozone1))
> test.subset <- (1:nrow(ozone1))[-train.subset]
> 
> # all the following models should be identical
> a <- earth(ozone1[,-1], ozone1[,1], subset=train.subset, nprune=7, degree=2)
> printh(a)
===a 
Selected 7 of 21 terms, and 5 of 9 predictors (nprune=7)
Termination condition: Reached nk 21
Importance: temp, ibh, humidity, doy, dpg, vh-unused, wind-unused, ...
Number of terms at each degree of interaction: 1 4 2
GCV 17.531    RSS 4084.192    GRSq 0.7243851    RSq 0.7549275
> plot(a)
> if (PLOT)
+     plotmo(a, caption="test subset: earth(ozone1[,-1], ozone1[,1], subset=train.subset)", trace=-1)
> 
> a <- earth(ozone1[train.subset,-1], ozone1[train.subset,1], nprune=7, degree=2)
> printh(a)
===a 
Selected 7 of 21 terms, and 5 of 9 predictors (nprune=7)
Termination condition: Reached nk 21
Importance: temp, ibh, humidity, doy, dpg, vh-unused, wind-unused, ...
Number of terms at each degree of interaction: 1 4 2
GCV 17.531    RSS 4084.192    GRSq 0.7243851    RSq 0.7549275
> if (PLOT)
+     plotmo(a, caption="test subset: earth(ozone1[train.subset,-1], ozone1[train.subset,1]", trace=-1)
> 
> a <- earth(O3 ~ ., data=ozone1, subset=train.subset, nprune=7, degree=2)
> printh(a)
===a 
Selected 7 of 21 terms, and 5 of 9 predictors (nprune=7)
Termination condition: Reached nk 21
Importance: temp, ibh, humidity, doy, dpg, vh-unused, wind-unused, ...
Number of terms at each degree of interaction: 1 4 2
GCV 17.531    RSS 4084.192    GRSq 0.7243851    RSq 0.7549275
> if (PLOT)
+     plotmo(a, caption="test subset: earth(O3 ~ ., data=ozone1, subset=train.subset", trace=-1)
> 
> y <- ozone1[test.subset, 1]
> yhat <- predict(a, newdata = ozone1[test.subset, -1])
> printh(1 - sum((y - yhat)^2)/sum((y - mean(y))^2)) # print RSquared
===1 - sum((y - yhat)^2)/sum((y - mean(y))^2) [1] 0.7922595
> 
> cat("--- update -------------------------\n")
--- update -------------------------
> 
> a <- earth(O3 ~ ., data=ozone1, degree=2)
> printh(update(a, penalty = -1, ponly=TRUE))
===update(a, penalty = -1, ponly = TRUE) 
Selected 21 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 10 10
GCV 10.85657    RSS 3582.667    GRSq 0.8303292    RSq 0.8303292
> printh(update(a, penalty = 10, ponly=TRUE))
===update(a, penalty = 10, ponly = TRUE) 
Selected 11 of 21 terms, and 8 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh-unused
Number of terms at each degree of interaction: 1 5 5
GCV 17.30867    RSS 3795.372    GRSq 0.7311301    RSq 0.8202558
> a <- earth(O3 ~ ., data=ozone1, nk=31, pmethod="n", degree=2)
> a.none <- printh(update(a, nprune=10, pmethod="n"))
===update(a, nprune = 10, pmethod = "n") 
Selected 10 of 31 terms, and 5 of 9 predictors (pmethod="none") (nprune=10)
Termination condition: Reached nk 31
Importance: temp, ibt-unused, humidity, doy, dpg, vis-unused, wind-unused, ...
Number of terms at each degree of interaction: 1 6 3
GCV 14.03861    RSS 3996.421    GRSq 0.7819266    RSq 0.8107343
> printh(update(a.none, pmethod="b"))
===update(a.none, pmethod = "b") 
Selected 10 of 31 terms, and 8 of 9 predictors (nprune=10)
Termination condition: Reached nk 31
Importance: temp, ibt, humidity, doy, dpg, vis, wind, ibh, vh-unused
Number of terms at each degree of interaction: 1 5 4
GCV 14.03861    RSS 3996.421    GRSq 0.7819266    RSq 0.8107343
> printh(update(a.none, nprune=4, pmethod="e"))
===update(a.none, nprune = 4, pmethod = "e") 
Selected 4 of 31 terms, and 3 of 9 predictors (pmethod="exhaustive") (nprune=4)
Termination condition: Reached nk 31
Importance: temp, ibh, humidity, vh-unused, wind-unused, dpg-unused, ...
Number of terms at each degree of interaction: 1 2 1
GCV 18.56782    RSS 5815.792    GRSq 0.7115708    RSq 0.7245711
> a.updated <- update(a.none, nprune=10, pmethod="b")
> printh(a.updated)
===a.updated 
Selected 10 of 31 terms, and 8 of 9 predictors (nprune=10)
Termination condition: Reached nk 31
Importance: temp, ibt, humidity, doy, dpg, vis, wind, ibh, vh-unused
Number of terms at each degree of interaction: 1 5 4
GCV 14.03861    RSS 3996.421    GRSq 0.7819266    RSq 0.8107343
> a.backwards <- update(a, nprune=10, pmethod="b")
> printh(a.backwards)
===a.backwards 
Selected 10 of 31 terms, and 8 of 9 predictors (nprune=10)
Termination condition: Reached nk 31
Importance: temp, ibt, humidity, doy, dpg, vis, wind, ibh, vh-unused
Number of terms at each degree of interaction: 1 5 4
GCV 14.03861    RSS 3996.421    GRSq 0.7819266    RSq 0.8107343
> printh(all.equal(a.updated$bx, a.backwards$bx))
===all.equal(a.updated$bx, a.backwards$bx) [1] TRUE
> a <- earth(O3 ~ ., data=ozone1, nk=31, nprune=10, pmethod="b", degree=2)
> printh(a)
===a 
Selected 10 of 31 terms, and 8 of 9 predictors (nprune=10)
Termination condition: Reached nk 31
Importance: temp, ibt, humidity, doy, dpg, vis, wind, ibh, vh-unused
Number of terms at each degree of interaction: 1 5 4
GCV 14.03861    RSS 3996.421    GRSq 0.7819266    RSq 0.8107343
> printh(all.equal(a$bx, a.backwards$bx))
===all.equal(a$bx, a.backwards$bx) [1] TRUE
> 
> cat("--- Auto.linpreds -----------------------------\n")
--- Auto.linpreds -----------------------------
> 
> set.seed(2017)
> x1 <- runif(10)
> x2 <- runif(10)
> y <- x1 + x2
> data=data.frame(x1=x1, x2=x2, y=y)
> par(mfrow = c(6, 4), mar = c(3, 3, 3, 1), mgp = c(1.5, 0.5, 0))
> 
> expect.err(try(earth(y~., data=data, Auto.linpr=99)), "Auto.linpreds=99 but it should be FALSE, TRUE, 0, or 1")
Error : Auto.linpreds=99 but it should be FALSE, TRUE, 0, or 1
Got expected error from try(earth(y ~ ., data = data, Auto.linpr = 99))
> 
> a <- earth(y~., data=data, trace=2) # default Auto.linpreds=TRUE
x[10,2] with colnames x1 x2
y[10,1] with colname y, and values 1.599, 0.5392, 0.4943, 0.7207...
Forward pass: minspan 3 endspan 4   x[10,2] 160 Bytes   bx[10,21] 1.64 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2     -0.3656 0.5785       0.5785    2           x2     0.43208  2   3         1 
4      1.0000 1.0000       0.4215    1           x1    0.039322< 4             1 final (max RSq)

Reached maximum RSq 0.9990 at 5 terms, 4 terms used (RSq 1.0000)
After forward pass GRSq 1.000 RSq 1.000
Forward pass complete: 5 terms, 4 terms used
Prune backward penalty 2 nprune null: selected 4 of 4 terms, and 2 of 2 preds
After pruning pass GRSq 1 RSq 1
> print(summary(a, style="pmax"))
Call: earth(formula=y~., data=data, trace=2)

y =
  0.4320778
  + 1 * x1                               
  - 1 * pmax(0,  0.4320778 -         x2) 
  + 1 * pmax(0,         x2 -  0.4320778) 

Selected 4 of 4 terms, and 2 of 2 predictors
Termination condition: Reached maximum RSq 0.9990 at 4 terms
Importance: x2, x1
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> plotmo(a, extend=.3, ylim=c(.2, 1.7),
+       do.par=FALSE, pt.col=2, jitter=0,
+       main=c("default Auto.linpreds=T", ""))
 plotmo grid:    x1        x2
           0.470681 0.4657348
> empty.plot()
> empty.plot()
> 
> a1 <- earth(y~., data=data, trace=2, Auto.linpreds=FALSE)
x[10,2] with colnames x1 x2
y[10,1] with colname y, and values 1.599, 0.5392, 0.4943, 0.7207...
Forward pass: minspan 3 endspan 4   x[10,2] 160 Bytes   bx[10,21] 1.64 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2     -0.3656 0.5785       0.5785    2           x2     0.43208  2   3         1 
4      1.0000 1.0000       0.4215    1           x1    0.039322< 4             1 final (max RSq)

Reached maximum RSq 0.9990 at 5 terms, 4 terms used (RSq 1.0000)
After forward pass GRSq 1.000 RSq 1.000
Forward pass complete: 5 terms, 4 terms used
Prune backward penalty 2 nprune null: selected 4 of 4 terms, and 2 of 2 preds
After pruning pass GRSq 1 RSq 1
> print(summary(a1, style="pmax"))
Call: earth(formula=y~., data=data, trace=2, Auto.linpreds=FALSE)

y =
  0.4714001
  + 1 * pmax(0,         x1 - 0.03932234) 
  - 1 * pmax(0,  0.4320778 -         x2) 
  + 1 * pmax(0,         x2 -  0.4320778) 

Selected 4 of 4 terms, and 2 of 2 predictors
Termination condition: Reached maximum RSq 0.9990 at 4 terms
Importance: x2, x1
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> plotmo(a1, extend=.3, ylim=c(.2, 1.7),
+       do.par=FALSE, pt.col=2, jitter=0,
+       main=c("Auto.linpreds=F", ""))
 plotmo grid:    x1        x2
           0.470681 0.4657348
> empty.plot()
> empty.plot()
> stopifnot(isTRUE(all.equal(predict(a), predict(a1))))
> 
> a2 <- earth(y~., data=data, trace=2, linpreds=TRUE, Auto.linpreds=FALSE)
x[10,2] with colnames x1 x2
y[10,1] with colname y, and values 1.599, 0.5392, 0.4943, 0.7207...
Linear predictors 1=x1 2=x2
Forward pass: minspan 3 endspan 4   x[10,2] 160 Bytes   bx[10,21] 1.64 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.3033 0.5785       0.5785    2           x2   0.0020208< 2             1 
4      1.0000 1.0000       0.4215    1           x1    0.039322< 3             1 final (max RSq)

Reached maximum RSq 0.9990 at 5 terms, 3 terms used (RSq 1.0000)
After forward pass GRSq 1.000 RSq 1.000
Forward pass complete: 5 terms, 3 terms used
Prune backward penalty 2 nprune null: selected 3 of 3 terms, and 2 of 2 preds
After pruning pass GRSq 1 RSq 1
> print(summary(a2, style="pmax"))
Call: earth(formula=y~., data=data, trace=2, linpreds=TRUE,
            Auto.linpreds=FALSE)

y =
  -2.808667e-16
  + 1 * x1                                 
  + 1 * x2                                 

Selected 3 of 3 terms, and 2 of 2 predictors
Termination condition: Reached maximum RSq 0.9990 at 3 terms
Importance: x2, x1
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> plotmo(a2, extend=.3, ylim=c(.2, 1.7),
+       do.par=FALSE, pt.col=2, jitter=0,
+       main=c("linpreds=T, Auto.linpreds=F", ""))
 plotmo grid:    x1        x2
           0.470681 0.4657348
> empty.plot()
> empty.plot()
> stopifnot(isTRUE(all.equal(predict(a), predict(a2))))
> 
> a3 <- earth(y~., data=data, linpreds="x1", Auto.linpreds=FALSE)
> print(summary(a3, style="pmax"))
Call: earth(formula=y~., data=data, linpreds="x1", Auto.linpreds=FALSE)

y =
  0.4320778
  + 1 * x1                               
  - 1 * pmax(0,  0.4320778 -         x2) 
  + 1 * pmax(0,         x2 -  0.4320778) 

Selected 4 of 4 terms, and 2 of 2 predictors
Termination condition: Reached maximum RSq 0.9990 at 4 terms
Importance: x2, x1
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> plotmo(a3, extend=.3, ylim=c(.2, 1.7),
+       do.par=FALSE, pt.col=2, jitter=0,
+       main=c("linpreds=x1, Auto.linpreds=F", ""))
 plotmo grid:    x1        x2
           0.470681 0.4657348
> empty.plot()
> empty.plot()
> stopifnot(isTRUE(all.equal(predict(a), predict(a3))))
> 
> a4 <- earth(y~., data=data, linpreds="x2", Auto.linpreds=FALSE)
> print(summary(a4, style="pmax"))
Call: earth(formula=y~., data=data, linpreds="x2", Auto.linpreds=FALSE)

y =
  0.03932234
  + 1 * x2                                 
  + 1 * pmax(0,          x1 -  0.03932234) 

Selected 3 of 3 terms, and 2 of 2 predictors
Termination condition: Reached maximum RSq 0.9990 at 3 terms
Importance: x2, x1
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> plotmo(a4, extend=.3, ylim=c(.2, 1.7),
+       do.par=FALSE, pt.col=2, jitter=0,
+       main=c("linpreds=x2, Auto.linpreds=F", ""))
 plotmo grid:    x1        x2
           0.470681 0.4657348
> empty.plot()
> empty.plot()
> stopifnot(isTRUE(all.equal(predict(a), predict(a4))))
> 
> # x,y interface
> a5 <- earth(data[,1:2], data[,3], Auto.linpreds=FALSE)
> print(summary(a5, style="pmax"))
Call: earth(x=data[,1:2], y=data[,3], Auto.linpreds=FALSE)

data[, 3] =
  0.4714001
  + 1 * pmax(0,         x1 - 0.03932234) 
  - 1 * pmax(0,  0.4320778 -         x2) 
  + 1 * pmax(0,         x2 -  0.4320778) 

Selected 4 of 4 terms, and 2 of 2 predictors
Termination condition: Reached maximum RSq 0.9990 at 4 terms
Importance: x2, x1
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> plotmo(a5, extend=.3, ylim=c(.2, 1.7),
+       do.par=FALSE, pt.col=2, jitter=0,
+       main=c("x,y interface", ""))
 plotmo grid:    x1        x2
           0.470681 0.4657348
> empty.plot()
> empty.plot()
> stopifnot(isTRUE(all.equal(as.vector(predict(a1)), as.vector(predict(a5)))))
> par(org.par)
> 
> # more complicated example (with Auto.linpreds=TRUE, vh enters linearly in a degree2 term)
> data(ozone1)
> oz <- ozone1[1:50,]
> mod.none1 <- earth(O3~., data=oz, degree=2, nk=15, pmethod="none") # default Auto.linpreds=TRUE
> print(summary(mod.none1))
Call: earth(formula=O3~., data=oz, pmethod="none", degree=2, nk=15)

                    coefficients
(Intercept)            4.2036778
h(5720-vh)             0.0331735
h(vh-5720)             0.0145381
h(4-wind)              1.1184678
h(wind-4)              0.1767766
h(28-humidity)        -0.1729997
h(humidity-28)        -7.3870298
h(174-ibt)            -0.0109694
h(ibt-174)            -0.0151749
h(45-doy)             -0.0433483
h(doy-45)              0.1827167
h(doy-61)             -0.2544981
vh * h(humidity-28)    0.0012973

Selected 13 of 13 terms, and 5 of 9 predictors (pmethod="none")
Termination condition: Reached nk 15
Importance: humidity, vh, doy, wind, ibt, temp-unused, ibh-unused, ...
Number of terms at each degree of interaction: 1 11 1
GCV 7.21889    RSS 52.12038    GRSq -0.05294658    RSq 0.8416852
> mod.none2 <- earth(O3~., data=oz, degree=2, nk=15, pmethod="none", Auto.linpreds=FALSE)
> print(summary(mod.none2))
Call: earth(formula=O3~., data=oz, pmethod="none", degree=2, nk=15,
            Auto.linpreds=FALSE)

                            coefficients
(Intercept)                    4.2036778
h(5720-vh)                     0.0331735
h(vh-5720)                     0.0145381
h(4-wind)                      1.1184678
h(wind-4)                      0.1767766
h(28-humidity)                -0.1729997
h(humidity-28)                -0.4464325
h(174-ibt)                    -0.0109694
h(ibt-174)                    -0.0151749
h(45-doy)                     -0.0433483
h(doy-45)                      0.1827167
h(doy-61)                     -0.2544981
h(vh-5350) * h(humidity-28)    0.0012973

Selected 13 of 13 terms, and 5 of 9 predictors (pmethod="none")
Termination condition: Reached nk 15
Importance: humidity, vh, doy, wind, ibt, temp-unused, ibh-unused, ...
Number of terms at each degree of interaction: 1 11 1
GCV 7.21889    RSS 52.12038    GRSq -0.05294658    RSq 0.8416852
> stopifnot(all.equal(predict(mod.none1), predict(mod.none2)))
> 
> # example figure in inst/doc
> par(mfrow=c(2,2), mar=c(4, 3.2, 3, 3), mgp=c(1.6, 0.6, 0), cex = 0.7)
> set.seed(2017)
> offset <- 98
> data.autolin <- data.frame(x=offset+(1:10), y=offset+(1:10))
> autolinFALSE <- earth(y~x, data=data.autolin, Auto.linpreds=FALSE)
> print(summary(autolinFALSE, style="max"))
Call: earth(formula=y~x, data=data.autolin, Auto.linpreds=FALSE)

y =
  99
  + 1 * max(0,  x - 99) 

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: Reached maximum RSq 0.9990 at 2 terms
Importance: x
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> set.seed(2017) # for same jitter on this and previous graph
> plotmo(autolinFALSE, extend=.3, do.par=FALSE, pt.col="red", lwd=2,
+        main="Auto.linpreds = FALSE",
+        xaxt="n", yaxt="n", jitter=1, cex.main=1,
+        xlim=offset+c(-2,13), ylim=offset+c(-3,13))
> legend(x="topleft", legend=c("data", "earth model"),
+        lty=c(0, 1), lwd=c(0, 2), pch=c(20, NA), col=c("red", 1))
> text(x=offset+3.8, y=offset-1.2, cex=.9, "The knot happens to be at the")
> text(x=offset+4,   y=offset-2.4, cex=.9, "minimum value of the predictor")
> 
> autolinTRUE <- earth(y~x, data=data.autolin) # default Auto.linpreds=TRUE
> print(summary(autolinTRUE, style="max"))
Call: earth(formula=y~x, data=data.autolin)

y =
  -0
  + 1 * x                

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: Reached maximum RSq 0.9990 at 2 terms
Importance: x
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> set.seed(2017) # for same jitter on this and next graph
> plotmo(autolinTRUE, extend=.3, do.par=FALSE, pt.col="red", lwd=2,
+        main="Auto.linpreds = TRUE   (default)",
+        xaxt="n", yaxt="n", jitter=1, cex.main=1,
+        xlim=offset+c(-2,13), ylim=offset+c(-3,13))
> legend(x="topleft", legend=c("data", "earth model"),
+        lty=c(0, 1), lwd=c(0, 2), pch=c(20, NA), col=c("red", 1))
> text(x=offset+4, y=offset-2.4, cex=.9, "Same data as previous graph")
> stopifnot(isTRUE(all.equal(predict(autolinTRUE), predict(autolinFALSE))))
> par(org.par)
> 
> # test Auto.linpreds with data sent in by a user
> ndata <- matrix(data=c(
+ -0.0781, -0.6109, -0.216, -1.5172, 0.8184, -1.1242,
+ -0.0781, -0.5885, -0.216, -1.3501, 0.8184, -0.8703,
+ -0.0781, -0.5885, -0.216, -1.3501, 0.8184, -0.9549,
+ -0.0781, -0.5885, -0.216, -1.3501, 1.4136, -0.8703,
+ -2.5759, -0.5885, 1.1665, -1.3501, 2.0089, -0.9549,
+ -2.5759, -0.5885, 1.1665, -1.3501, 2.0089, -0.8703,
+ -0.0781, -0.4937, -0.216, -0.9949, -0.372, -1.0396,
+ -0.0781, -0.4463, -0.216, -0.8278, -0.372, -0.447,
+ -0.0781, -0.4463, -0.216, -0.8278, -0.372, -0.701,
+ -0.0781, -0.4463, -0.216, -0.8278, -0.372, -0.6163,
+ -0.0781, -0.4463, -0.216, -0.8278, 0.8184, -0.447,
+ -0.0781, -0.4463, -0.216, -0.8278, 0.8184, -0.6163,
+ -0.0781, -0.4463, 1.1665, -0.8278, 0.8184, -0.447,
+ -0.0781, -0.4379, 1.1665, 0.2585, -0.372, -0.1085,
+ -0.0781, -0.2147, 1.1665, 0.0496, -0.372, -0.1085,
+ -0.0781, -0.2147, -0.216, 0.2585, -0.372, -0.0238,
+ -0.0781, -0.1589, -0.216, 0.2585, -0.372, -0.1931,
+ -0.0781, -0.1589, -0.216, 0.2585, -0.372, -0.1085,
+ -0.0781, -0.1589, 1.1665, 0.2585, -0.372, -0.1931,
+ -0.0781, -0.1589, -0.216, 0.2585, 0.8184, -0.1085,
+ -0.0781, -0.1589, -0.216, 0.2585, 0.8184, 0.0608,
+ -0.0781, -0.1589, -0.216, 1.0942, 0.8184, -0.0238,
+ -0.0781, 0.0643, 1.1665, 1.0942, -0.372, 0.2301,
+ -0.0781, 0.0643, -0.216, 1.0942, -1.5624, 0.3148,
+ -0.0781, 0.0643, -0.216, 1.0942, -0.9672, 0.1455,
+ -0.0781, 0.0643, 1.1665, 1.4284, 0.2232, 0.4841,
+ -0.0781, 0.1563, -0.216, 1.0942, -0.372, 0.5687,
+ 2.4197, 0.3432, -0.216, 1.0942, -1.5624, 1.0766,
+ -0.0781, 0.3432, -0.216, 1.0942, -1.5624, 1.1613,
+ -0.0781, 0.3432, 1.1665, 1.0942, 0.2232, 0.738,
+ 2.4197, 2.7145, -2.9811, 1.0942, -1.5624, 2.5156,
+ 2.4197, 4.3884, -2.9811, 1.0942, -1.5624, 3.5314),
+ ncol=6)
> colnames(ndata) <- c("x1", "x2", "x3", "x4", "x5", "y")
> ndata <- as.data.frame(ndata)
> 
> cat("Auto.linpreds=TRUE pmethod=\"none\":\n")
Auto.linpreds=TRUE pmethod="none":
> # trace==2 so we see "Fixed rank deficient bx by removing terms"
> # TODO why are we getting the rank deficient message?
> auto.linpreds.true.pmethod.none <- earth(y~., data=ndata, degree=2, nk=21, trace=2, pmethod="none")
x[32,5] with colnames x1 x2 x3 x4 x5
y[32,1] with colname y, and values -0.372, 0.5687, 2.42, 0.3432,...
Forward pass: minspan 4 endspan 9   x[32,5] 1.25 kB   bx[32,21] 5.25 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0583 0.3376       0.3376    1           x1     -0.9549  2   3         1 
4     -0.2012 0.4488       0.1112    3           x3     -0.0781  4   5         1 
6     -0.1801 0.5797        0.131    4           x4      -0.372< 6         2   2 
8     -0.2458 0.6681      0.08841    3           x3     -0.8278< 7         2   2 
10    -0.4175 0.7312      0.06304    3           x3     -0.8278< 8         3   2 
12    -0.8452 0.7677      0.03649    1           x1      -0.216  9             1 
14    -1.7625 0.7923      0.02464    1           x1     -2.5759< 10        4   2 
16   -13.8221 0.8111      0.01875    2           x2      -0.216  11  12        1 reject (negative GRSq)

Reached minimum GRSq -10 at 15 terms, 10 terms used (GRSq -14)
After forward pass GRSq -13.822 RSq 0.811
Forward pass complete: 15 terms, 10 terms used
Prune none penalty 3 nprune null: selected 10 of 10 terms, and 3 of 5 preds
After pruning pass GRSq -1.76 RSq 0.792
> print(summary(auto.linpreds.true.pmethod.none, decomp="none"))
Call: earth(formula=y~., data=ndata, pmethod="none", trace=2, degree=2, nk=21)

                    coefficients
(Intercept)            2.4332961
h(x1- -0.9549)        -0.9865989
h(-0.9549-x1)          6.9070794
h(x3- -0.0781)        -8.9336500
h(-0.0781-x3)          0.0165408
h(x1- -0.9549) * x4   -1.2581107
h(x1- -0.9549) * x3    6.4769097
h(-0.9549-x1) * x3    25.0101165
h(x1- -0.216)          1.8627919
x1 * h(x3- -0.0781)   -5.5959046

Selected 10 of 10 terms, and 3 of 5 predictors (pmethod="none")
Termination condition: GRSq -10 at 10 terms
Importance: x1, x4, x3, x2-unused, x5-unused
Number of terms at each degree of interaction: 1 5 4
GCV 8.371258    RSS 18.90073    GRSq -1.762519    RSq 0.792308
> cat("\nAuto.linpreds=FALSE pmethod=\"none\":\n")

Auto.linpreds=FALSE pmethod="none":
> auto.linpreds.false.pmethod.none <- earth(y~., data=ndata, degree=2, nk=21, trace=2, Auto.linpreds=FALSE, pmethod="none")
x[32,5] with colnames x1 x2 x3 x4 x5
y[32,1] with colname y, and values -0.372, 0.5687, 2.42, 0.3432,...
Forward pass: minspan 4 endspan 9   x[32,5] 1.25 kB   bx[32,21] 5.25 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0583 0.3376       0.3376    1           x1     -0.9549  2   3         1 
4     -0.2012 0.4488       0.1112    3           x3     -0.0781  4   5         1 
6     -0.1801 0.5797        0.131    4           x4      -0.372< 6         2   2 
8     -0.2458 0.6681      0.08841    3           x3     -0.8278< 7         2   2 
10    -0.4175 0.7312      0.06304    3           x3     -0.8278< 8         3   2 
12    -0.8452 0.7677      0.03649    1           x1      -0.216  9             1 
14    -1.7625 0.7923      0.02464    1           x1     -2.5759< 10        5   2 
16   -13.8221 0.8111      0.01875    2           x2      -0.216  11  12        1 reject (negative GRSq)

Reached minimum GRSq -10 at 15 terms, 12 terms used (GRSq -14)
After forward pass GRSq -13.822 RSq 0.811
Forward pass complete: 15 terms, 12 terms used
Fixed rank deficient bx by removing 2 terms, 10 terms remain
Prune none penalty 3 nprune null: selected 10 of 10 terms, and 3 of 5 preds
After pruning pass GRSq -1.76 RSq 0.792
> print(summary(auto.linpreds.false.pmethod.none, decomp="none"))
Call: earth(formula=y~., data=ndata, pmethod="none", trace=2, degree=2, nk=21,
            Auto.linpreds=FALSE)

                                coefficients
(Intercept)                         2.433296
h(x1- -0.9549)                     -1.684918
h(-0.9549-x1)                     -17.991545
h(x3- -0.0781)                     -3.590121
h(-0.0781-x3)                       9.087502
h(x1- -0.9549) * h(x4- -0.372)     -1.258111
h(x1- -0.9549) * h(x3- -0.8278)     0.881005
h(-0.9549-x1) * h(x3- -0.8278)     30.606021
h(x1- -0.216)                       1.862792
h(x1- -2.5759) * h(-0.0781-x3)     -5.595905

Selected 10 of 10 terms, and 3 of 5 predictors (pmethod="none")
Termination condition: GRSq -10 at 10 terms
Importance: x1, x4, x3, x2-unused, x5-unused
Number of terms at each degree of interaction: 1 5 4
GCV 8.371258    RSS 18.90073    GRSq -1.762519    RSq 0.792308
> stopifnot(isTRUE(all.equal(predict(auto.linpreds.true.pmethod.none), predict(auto.linpreds.false.pmethod.none))))
> 
> cat("\nAuto.linpreds=TRUE:\n")

Auto.linpreds=TRUE:
> auto.linpreds.true <- earth(y~., data=ndata, degree=2, nk=21, trace=2)
x[32,5] with colnames x1 x2 x3 x4 x5
y[32,1] with colname y, and values -0.372, 0.5687, 2.42, 0.3432,...
Forward pass: minspan 4 endspan 9   x[32,5] 1.25 kB   bx[32,21] 5.25 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0583 0.3376       0.3376    1           x1     -0.9549  2   3         1 
4     -0.2012 0.4488       0.1112    3           x3     -0.0781  4   5         1 
6     -0.1801 0.5797        0.131    4           x4      -0.372< 6         2   2 
8     -0.2458 0.6681      0.08841    3           x3     -0.8278< 7         2   2 
10    -0.4175 0.7312      0.06304    3           x3     -0.8278< 8         3   2 
12    -0.8452 0.7677      0.03649    1           x1      -0.216  9             1 
14    -1.7625 0.7923      0.02464    1           x1     -2.5759< 10        4   2 
16   -13.8221 0.8111      0.01875    2           x2      -0.216  11  12        1 reject (negative GRSq)

Reached minimum GRSq -10 at 15 terms, 10 terms used (GRSq -14)
After forward pass GRSq -13.822 RSq 0.811
Forward pass complete: 15 terms, 10 terms used
Prune backward penalty 3 nprune null: selected 4 of 10 terms, and 3 of 5 preds
After pruning pass GRSq 0.209 RSq 0.546
> print(summary(auto.linpreds.true, decomp="none"))
Call: earth(formula=y~., data=ndata, trace=2, degree=2, nk=21)

                    coefficients
(Intercept)             1.371239
h(x3- -0.0781)         -1.882810
h(x1- -0.9549) * x4    -1.413220
h(-0.9549-x1) * x3      4.319452

Selected 4 of 10 terms, and 3 of 5 predictors
Termination condition: GRSq -10 at 10 terms
Importance: x1, x4, x3, x2-unused, x5-unused
Number of terms at each degree of interaction: 1 1 2
GCV 2.396481    RSS 41.35802    GRSq 0.20916    RSq 0.5455344
> cat("\nAuto.linpreds=FALSE:\n")

Auto.linpreds=FALSE:
> auto.linpreds.false <- earth(y~., data=ndata, degree=2, nk=21, trace=2, Auto.linpreds=FALSE)
x[32,5] with colnames x1 x2 x3 x4 x5
y[32,1] with colname y, and values -0.372, 0.5687, 2.42, 0.3432,...
Forward pass: minspan 4 endspan 9   x[32,5] 1.25 kB   bx[32,21] 5.25 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0583 0.3376       0.3376    1           x1     -0.9549  2   3         1 
4     -0.2012 0.4488       0.1112    3           x3     -0.0781  4   5         1 
6     -0.1801 0.5797        0.131    4           x4      -0.372< 6         2   2 
8     -0.2458 0.6681      0.08841    3           x3     -0.8278< 7         2   2 
10    -0.4175 0.7312      0.06304    3           x3     -0.8278< 8         3   2 
12    -0.8452 0.7677      0.03649    1           x1      -0.216  9             1 
14    -1.7625 0.7923      0.02464    1           x1     -2.5759< 10        5   2 
16   -13.8221 0.8111      0.01875    2           x2      -0.216  11  12        1 reject (negative GRSq)

Reached minimum GRSq -10 at 15 terms, 12 terms used (GRSq -14)
After forward pass GRSq -13.822 RSq 0.811
Forward pass complete: 15 terms, 12 terms used
Fixed rank deficient bx by removing 2 terms, 10 terms remain
Prune backward penalty 3 nprune null: selected 5 of 10 terms, and 3 of 5 preds
After pruning pass GRSq 0.223 RSq 0.643
> print(summary(auto.linpreds.false, decomp="none"))
Call: earth(formula=y~., data=ndata, trace=2, degree=2, nk=21,
            Auto.linpreds=FALSE)

                               coefficients
(Intercept)                        1.635321
h(-0.9549-x1)                    -12.155291
h(x3- -0.0781)                    -1.555091
h(x1- -0.9549) * h(x4- -0.372)    -1.220702
h(-0.9549-x1) * h(x3- -0.8278)    22.975120

Selected 5 of 10 terms, and 3 of 5 predictors
Termination condition: GRSq -10 at 10 terms
Importance: x1, x4, x3, x2-unused, x5-unused
Number of terms at each degree of interaction: 1 2 2
GCV 2.354961    RSS 32.4543    GRSq 0.2228618    RSq 0.6433736
> # following fails because of different pruning because of different term count
> # stopifnot(isTRUE(all.equal(predict(auto.linpreds.true), predict(auto.linpreds.false))))
> 
> cat("--- Force.xtx.prune -----------------------------\n")
--- Force.xtx.prune -----------------------------
> 
> expect.err(try(earth(Volume ~ ., data = trees, Force.xtx.prune=TRUE, pmethod="ex")), "not allowed with") # pmethod="ex" cannot be used with Force.xtx.prune
Error : pmethod="exhaustive" is not allowed with 'eval.subsets.xtx'
Got expected error from try(earth(Volume ~ ., data = trees, Force.xtx.prune = TRUE, pmethod = "ex"))
> 
> m1 <- earth(Volume ~ ., data = trees)
> m2 <- earth(Volume ~ ., data = trees, Force.xtx.prune=TRUE)
> check.models.equal(m1, m2, "Force.xtx.prune test 1", check.subsets=FALSE, newdata=data.frame(Height=10, Girth=12))
Force.xtx.prune test 1: models not identical

mod1$rsq 0.9742029 != mod2$rsq 0.9742029 (although almost equal)
Force.xtx.prune test 1: Models are equivalent, within numerical tolerances

> 
> m1 <- earth(O3 ~ wind+temp, data = ozone1, nk=51)
> m2 <- earth(O3 ~ wind+temp, data = ozone1, nk=51, Force.xtx.prune=TRUE)
> check.models.equal(m1, m2, "Force.xtx.prune test 2", check.subsets=FALSE, newdata=ozone1[5:7,])
Force.xtx.prune test 2: models not identical

mod1$rsq 0.6647086 != mod2$rsq 0.6647086 (although almost equal)
Force.xtx.prune test 2: Models are equivalent, within numerical tolerances

> 
> # TODO The following exposes a bug in leaps(?).  It is described in
> # check.one.term.per.step in the earth R code.  The test is commented out
> # because this bug causes a discrepancy with Force.xtx.prune (although
> # usually the bug does not cause any problems).
> #
> # m1 <- earth(O3 ~ ., data = ozone1, nk=51, degree=2, trace=5)
> # m2 <- earth(O3 ~ ., data = ozone1, nk=51, degree=2, Force.xtx.prune=TRUE)
> # check.models.equal(m1, m2, "Force.xtx.prune test 3", check.subsets=FALSE)
> 
> cat("--- extractAIC.earth ----------------------------\n")
--- extractAIC.earth ----------------------------
> 
> a <-earth(O3 ~ ., data=ozone1, degree=2)
> cat("Ignore 10 warnings: extractAIC.earth: using GCV instead of AIC\n")
Ignore 10 warnings: extractAIC.earth: using GCV instead of AIC
> printh(drop1(a), expect.warning=TRUE)
===drop1(a)  expect warning -->Warning: extractAIC.earth: returning GCV instead of AIC
Warning: extractAIC.earth: returning GCV instead of AIC
Warning: extractAIC.earth: returning GCV instead of AIC
Warning: extractAIC.earth: returning GCV instead of AIC
Warning: extractAIC.earth: returning GCV instead of AIC
Warning: extractAIC.earth: returning GCV instead of AIC
Warning: extractAIC.earth: returning GCV instead of AIC
Warning: extractAIC.earth: returning GCV instead of AIC
Warning: extractAIC.earth: returning GCV instead of AIC
Warning: extractAIC.earth: returning GCV instead of AIC
Single term deletions

Model:
O3 ~ vh + wind + humidity + temp + ibh + dpg + ibt + vis + doy
            Df    AIC
<none>         13.408
vh         0.0 13.486
wind       2.5 13.887
humidity -10.0 15.191
temp      -7.5 13.016
ibh        0.0 12.836
dpg        0.0 14.800
ibt       -7.5 13.736
vis       -7.5 14.785
doy       -2.5 15.353
> printh(drop1(a, warn=FALSE)) # repeat but with warnings suppressed
===drop1(a, warn = FALSE) 
Single term deletions

Model:
O3 ~ vh + wind + humidity + temp + ibh + dpg + ibt + vis + doy
            Df    AIC
<none>         13.408
vh         0.0 13.486
wind       2.5 13.887
humidity -10.0 15.191
temp      -7.5 13.016
ibh        0.0 12.836
dpg        0.0 14.800
ibt       -7.5 13.736
vis       -7.5 14.785
doy       -2.5 15.353
> 
> cat("--- fda and mda with earth -----------------------------------\n")
--- fda and mda with earth -----------------------------------
> 
> am <- fda(Species ~ ., data=iris, method=mars, degree=1, keepxy=TRUE)
> printh(am)
===am 
Call:
fda(formula = Species ~ ., data = iris, method = mars, degree = 1, 
    keepxy = TRUE)

Dimension: 2 

Percent Between-Group Variance Explained:
    v1     v2 
 92.73 100.00 

Training Misclassification Error: 0.02667 ( N = 150 )
> a <- fda(Species ~ ., data=iris, method=earth, degree=1, keepxy=TRUE)
> printh(a)
===a 
Call:
fda(formula = Species ~ ., data = iris, method = earth, degree = 1, 
    keepxy = TRUE)

Dimension: 2 

Percent Between-Group Variance Explained:
    v1     v2 
 97.97 100.00 

Training Misclassification Error: 0.04 ( N = 150 )
> printh(confusion(a))
===confusion(a) 
            true
predicted    setosa versicolor virginica
  setosa         50          0         0
  versicolor      0         47         3
  virginica       0          3        47
> if (PLOT) {
+     par(mar=c(3, 3, 2, .5))  # small margins and text to pack figs in
+     par(mgp=c(1.6, 0.6, 0))  # flatten axis elements
+     par(oma=c(0,0,4,0))      # make space for caption
+     layout(rbind(c(1,1,0,0), c(2,3,4,5), c(6,7,8,9)), heights=c(2,1,1))
+     plot(a)
+     plotmo(a$fit, nresponse=1, ylim=c(-1.5,1.5), clip=FALSE, do.par=FALSE, trace=-1)
+     plotmo(a$fit, nresponse=2, ylim=c(-1.5,1.5), clip=FALSE, do.par=FALSE, trace=-1)
+     mtext("fda test", outer=TRUE, font=2, line=1.5, cex=1)
+ }
> 
> data(glass)
> set.seed(123)
> samp <- sample(c(1:214), size=100, replace=FALSE)
> glass.train <- glass[samp,]
> glass.test <- glass[-samp,]
> am <- mda(Type ~ ., data=glass.train, method=mars,  keepxy=TRUE, degree=2)
> a <-  mda(Type ~ ., data=glass.train, method=earth, keepxy=TRUE, degree=2, keep.fitted=TRUE)
> printh(am)
===am 
Call:
mda(formula = Type ~ ., data = glass.train, method = mars, keepxy = TRUE, 
    degree = 2)

Dimension: 14 

Percent Between-Group Variance Explained:
    v1     v2     v3     v4     v5     v6     v7     v8     v9    v10    v11 
 50.58  74.19  86.94  92.11  95.37  97.20  98.32  99.16  99.64  99.88 100.00 
   v12    v13    v14 
100.00 100.00 100.00 

Training Misclassification Error: 0.2 ( N = 100 )

Deviance: 83.903 
> printh(a)
===a 
Call:
mda(formula = Type ~ ., data = glass.train, method = earth, keep.fitted = TRUE, 
    keepxy = TRUE, degree = 2)

Dimension: 8 

Percent Between-Group Variance Explained:
    v1     v2     v3     v4     v5     v6     v7     v8 
 46.60  74.43  85.71  92.48  95.56  98.06  99.20 100.00 

Training Misclassification Error: 0.22 ( N = 100 )

Deviance: 121.699 
> cat("mda with mars  ", attr(confusion(am), "error"), "\n")
mda with mars   0.2 
> cat("mda with earth ", attr(confusion(a),  "error"), "\n")
mda with earth  0.22 
> if (PLOT) {
+     plot(a$fit, caption="mda on glass data", nresponse=1)
+     plotmo(a$fit, nresponse=9, clip=FALSE, ylim=NA, caption="mda on glass data", trace=-1)
+ }
> 
> cat("\n---- update and keepxy, formula interface --------------------------\n")

---- update and keepxy, formula interface --------------------------
> 
> new.trees <- trees + c(1,2,3,4)
> new.trees <- new.trees[, -c(20:23)]
> a.formula <- earth(Volume ~ ., subset=rep(TRUE, nrow(trees)), data = trees)
> cat("\nupdate(a, trace=1)\n")

update(a, trace=1)
> a.formula.1update <- update(a.formula, trace=1)
update.earth: using 31 by 3 data argument from original call to earth
update.earth: using 31 by 1 subset argument from original call to earth
x[31,2] with colnames Girth Height
y[31,1] with colname Volume, and values 10.3, 10.3, 10.2, 16.4, 18.8,...
31 cases after taking subset
Skipped forward pass
Prune backward penalty 2 nprune null: selected 4 of 5 terms, and 2 of 2 preds
After pruning pass GRSq 0.96 RSq 0.974
> a.formula.1  <- earth(Volume ~ ., subset=rep(TRUE, nrow(trees)), data = trees)
> newdata.global <- trees[seq(from=nrow(trees), to=1, by=-5),]
> check.models.equal(a.formula.1update, a.formula.1, msg="a1update a1", newdata=newdata.global)
a1update a1: models identical

> 
> cat("\nupdate(a.formula, data=new.trees, trace=1)\n")

update(a.formula, data=new.trees, trace=1)
> a.formula.2update <- update(a.formula, data=new.trees, trace=1)
update.earth: using 31 by 1 subset argument from original call to earth
x[31,2] with colnames Girth Height
y[31,1] with colname Volume, and values 13.3, 14.3, 11.2, 18.4, 21.8,...
31 cases after taking subset
Forward pass term 1, 2, 4, 6, 8, 10, 12
RSq changed by less than 0.001 at 11 terms, 8 terms used (DeltaRSq 0.00016)
After forward pass GRSq 0.735 RSq 0.942
Prune backward penalty 2 nprune null: selected 5 of 8 terms, and 2 of 2 preds
After pruning pass GRSq 0.886 RSq 0.938
> a.formula.2  <- earth(Volume ~ ., subset=rep(TRUE, nrow(trees)), data = new.trees)
> check.models.equal(a.formula.2update, a.formula.2, msg="a2update a2", newdata=newdata.global)
a2update a2: models identical

> 
> cat("\nupdate(a.formula, wp=2, trace=1)\n")

update(a.formula, wp=2, trace=1)
> a.formula.3update <- update(a.formula, wp=2, trace=1)
update.earth: using 31 by 3 data argument from original call to earth
update.earth: using 31 by 1 subset argument from original call to earth
x[31,2] with colnames Girth Height
y[31,1] with colname Volume, and values 10.3, 10.3, 10.2, 16.4, 18.8,...
31 cases after taking subset
Forward pass term 1, 2, 4, 6
RSq changed by less than 0.001 at 5 terms (DeltaRSq 0.00087)
After forward pass GRSq 0.947 RSq 0.976
Prune backward penalty 2 nprune null: selected 4 of 5 terms, and 2 of 2 preds
After pruning pass GRSq 0.96 RSq 0.974
> a.formula.3  <- earth(Volume ~ ., subset=rep(TRUE, nrow(trees)), data = trees, wp=2)
> check.models.equal(a.formula.3update, a.formula.3, msg="a3update a3", newdata=newdata.global)
a3update a3: models identical

> 
> cat("\nupdate(a.formula, subset=subset.new, trace=1)\n")

update(a.formula, subset=subset.new, trace=1)
> subset.new <- rep(TRUE, nrow(trees))
> subset.new[1:4] = FALSE
> a.formula.4update <- update(a.formula, subset=subset.new, trace=1)
update.earth: using 31 by 3 data argument from original call to earth
x[31,2] with colnames Girth Height
y[31,1] with colname Volume, and values 10.3, 10.3, 10.2, 16.4, 18.8,...
27 cases after taking subset
Forward pass term 1, 2, 4, 6
RSq changed by less than 0.001 at 5 terms (DeltaRSq 0.00037)
After forward pass GRSq 0.925 RSq 0.972
Prune backward penalty 2 nprune null: selected 4 of 5 terms, and 2 of 2 preds
After pruning pass GRSq 0.947 RSq 0.969
> a.formula.4  <- earth(Volume ~ ., data = trees, subset=subset.new)
> check.models.equal(a.formula.4update, a.formula.4, msg="a4update a4", newdata=newdata.global)
a4update a4: models identical

> 
> # now use keepxy=TRUE
> 
> a.formula <- earth(Volume ~ ., wp=1, data = trees, keepxy=TRUE)
> 
> cat("\nupdate(a.formula, trace=1)\n")

update(a.formula, trace=1)
> a.formula.5update <- update(a.formula, trace=1)
update.earth: using 31 by 3 data saved by keepxy in original call to earth
update.earth: using 1 by 1 wp saved by keepxy in original call to earth
x[31,2] with colnames Girth Height
y[31,1] with colname Volume, and values 10.3, 10.3, 10.2, 16.4, 18.8,...
Skipped forward pass
Prune backward penalty 2 nprune null: selected 4 of 5 terms, and 2 of 2 preds
After pruning pass GRSq 0.96 RSq 0.974
> a.formula.5  <- earth(Volume ~ ., wp=1, data = trees, keepxy=TRUE)
> check.models.equal(a.formula.5update, a.formula.5, msg="a5update a5", newdata=newdata.global)
a5update a5: models identical

> 
> cat("\nupdate(a.formula, data=new.trees, trace=1)\n")

update(a.formula, data=new.trees, trace=1)
> a.formula.6update <- update(a.formula, data=new.trees, trace=1)
update.earth: using 1 by 1 wp saved by keepxy in original call to earth
x[31,2] with colnames Girth Height
y[31,1] with colname Volume, and values 13.3, 14.3, 11.2, 18.4, 21.8,...
Forward pass term 1, 2, 4, 6, 8, 10, 12
RSq changed by less than 0.001 at 11 terms, 8 terms used (DeltaRSq 0.00016)
After forward pass GRSq 0.735 RSq 0.942
Prune backward penalty 2 nprune null: selected 5 of 8 terms, and 2 of 2 preds
After pruning pass GRSq 0.886 RSq 0.938
> a.formula.6  <- earth(Volume ~ ., wp=1, data = new.trees, keepxy=TRUE)
> check.models.equal(a.formula.6update, a.formula.6, msg="a6update a6", newdata=newdata.global)
a6update a6: models identical

> 
> cat("\nupdate(a.formula, wp=2, trace=1)\n")

update(a.formula, wp=2, trace=1)
> a.formula.7update <- update(a.formula, wp=2, trace=1)
update.earth: using 31 by 3 data saved by keepxy in original call to earth
x[31,2] with colnames Girth Height
y[31,1] with colname Volume, and values 10.3, 10.3, 10.2, 16.4, 18.8,...
Forward pass term 1, 2, 4, 6
RSq changed by less than 0.001 at 5 terms (DeltaRSq 0.00087)
After forward pass GRSq 0.947 RSq 0.976
Prune backward penalty 2 nprune null: selected 4 of 5 terms, and 2 of 2 preds
After pruning pass GRSq 0.96 RSq 0.974
> a.formula.7  <- earth(Volume ~ ., wp=2, data = trees, keepxy=TRUE)
> check.models.equal(a.formula.7update, a.formula.7, msg="a7update a7", newdata=newdata.global)
a7update a7: models identical

> 
> cat("\n----- update and keepxy, xy interface--------------------------\n")

----- update and keepxy, xy interface--------------------------
> 
> Volume <- trees$Volume
> x <- cbind(trees$Height, trees$Volume)
> colnames(x) <- c("Height", "Volume")
> 
> new.x <- cbind(new.trees$Height, new.trees$Volume)
> colnames(new.x) <- c("Height", "Volume")
> 
> a <- earth(x, Volume, subset=rep(TRUE, nrow(trees)))
> cat("\nupdate(a, trace=1)\n")

update(a, trace=1)
> a1update <- update(a, trace=1)
update.earth: using 31 by 2 x argument from original call to earth
update.earth: using 31 by 1 y argument from original call to earth
update.earth: using 31 by 1 subset argument from original call to earth
x[31,2] with colnames Height Volume
y[31,1] with colname Volume, and values 10.3, 10.3, 10.2, 16.4, 18.8,...
31 cases after taking subset
Skipped forward pass
Prune backward penalty 2 nprune null: selected 2 of 2 terms, and 1 of 2 preds
After pruning pass GRSq 1 RSq 1
> a1  <- earth(x, Volume, subset=rep(TRUE, nrow(trees)))
> check.models.equal(a1update, a1, msg="a1update a1", newdata=newdata.global)
a1update a1: models identical

> 
> cat("\nupdate(a, x=new.x, trace=1)\n")

update(a, x=new.x, trace=1)
> a2update <- update(a, x=new.x, trace=1)
update.earth: using 31 by 1 y argument from original call to earth
update.earth: using 31 by 1 subset argument from original call to earth
x[31,2] with colnames Height Volume
y[31,1] with colname Volume, and values 10.3, 10.3, 10.2, 16.4, 18.8,...
31 cases after taking subset
Forward pass term 1, 2, 4
RSq changed by less than 0.001 at 3 terms (DeltaRSq 0.00028)
After forward pass GRSq 0.992 RSq 0.996
Prune backward penalty 2 nprune null: selected 3 of 3 terms, and 1 of 2 preds
After pruning pass GRSq 0.994 RSq 0.995
> a2  <- earth(new.x, Volume, subset=rep(TRUE, nrow(trees)))
> check.models.equal(a2update, a2, msg="a2update a2", newdata=newdata.global)
a2update a2: models identical

> 
> cat("\nupdate(a, wp=2, trace=0)\n")

update(a, wp=2, trace=0)
> a3update <- update(a, wp=2, trace=0)
> a3  <- earth(x, Volume, subset=rep(TRUE, nrow(trees)), wp=2)
> check.models.equal(a3update, a3, msg="a3update a3", newdata=newdata.global)
a3update a3: models identical

> 
> cat("\nupdate(a, subset=subset.new, trace=4)\n")

update(a, subset=subset.new, trace=4)
> subset.new <- rep(TRUE, nrow(trees))
> subset.new[1:4] = FALSE
> a4update <- update(a, subset=subset.new, trace=4)
update.earth: using 31 by 2 x argument from original call to earth
update.earth: using 31 by 1 y argument from original call to earth
Call: earth(x=x, y=Volume, subset=subset.new, trace=4)

x[31,2]:
    Height Volume
1       70   10.3
2       65   10.3
3       63   10.2
...     72   16.4
31      87   77.0

y[31,1]:
    Volume
1     10.3
2     10.3
3     10.2
...   16.4
31    77.0

27 cases after taking subset

Forward pass: minspan 4 endspan 8   x[27,2] 432 Bytes   bx[27,21] 4.43 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      1.0000 1.0000            1    2       Volume        15.6< 2             1 final (max RSq)

Reached maximum RSq 0.9990 at 3 terms, 2 terms used (RSq 1.0000)
After forward pass GRSq 1.000 RSq 1.000
Forward pass complete: 3 terms, 2 terms used

Using EvalSubsetsUsingXtx (rather than leaps) because ncol(bx) <= 2
     nTerms iTerm    DeltaRss     RSq
          2     2      6527.9  0.0000 min

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
chosen    2      1.0000  1.0000     1.0000      1  1 2

Prune backward penalty 2 nprune null: selected 2 of 2 terms, and 1 of 2 preds
After pruning pass GRSq 1 RSq 1
> a4  <- earth(x, Volume, subset=subset.new)
> check.models.equal(a4update, a4, msg="a4update a4", newdata=newdata.global)
a4update a4: models identical

> 
> # now use keepxy=TRUE
> 
> a <- earth(x, Volume, wp=1, keepxy=TRUE)
> 
> cat("\nupdate(a, trace=4)\n")

update(a, trace=4)
> a5update <- update(a, trace=4)
update.earth: using 31 by 2 x saved by keepxy in original call to earth
update.earth: using 31 by 1 y saved by keepxy in original call to earth
update.earth: using 1 by 1 wp saved by keepxy in original call to earth
Call: earth(x=matrix[31,2], y=c(10.3,10.3,10...), wp=1, keepxy=TRUE, trace=4,
            Object=a)

x[31,2]:
    Height Volume
1       70   10.3
2       65   10.3
3       63   10.2
...     72   16.4
31      87   77.0

y[31,1]:
    Volume
1     10.3
2     10.3
3     10.2
...   16.4
31    77.0

Skipped forward pass
Using EvalSubsetsUsingXtx (rather than leaps) because ncol(bx) <= 2
     nTerms iTerm    DeltaRss     RSq
          2     2      8106.1 -0.0000 min

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
chosen    2      1.0000  1.0000     1.0000      1  1 2

Prune backward penalty 2 nprune null: selected 2 of 2 terms, and 1 of 2 preds
After pruning pass GRSq 1 RSq 1
> a5  <- earth(x, Volume, wp=1, keepxy=TRUE)
> check.models.equal(a5update, a5, msg="a5update a5", newdata=newdata.global)
a5update a5: models identical

> 
> cat("\nupdate(a, x=new.x, trace=4)\n")

update(a, x=new.x, trace=4)
> a6update <- update(a, x=new.x, trace=4)
update.earth: using 31 by 1 y saved by keepxy in original call to earth
update.earth: using 1 by 1 wp saved by keepxy in original call to earth
Call: earth(x=new.x, y=c(10.3,10.3,10...), wp=1, keepxy=TRUE, trace=4)

x[31,2]:
    Height Volume
1       74   13.3
2       66   14.3
3       65   11.2
...     75   18.4
31      89   78.0

y[31,1]:
    Volume
1     10.3
2     10.3
3     10.2
...   16.4
31    77.0

Forward pass: minspan 4 endspan 8   x[31,2] 496 Bytes   bx[31,21] 5.09 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.9938 0.9954       0.9954    2       Volume        37.3  2   3         1 
4      0.9919 0.9956    0.0002782    1       Height          75  4   5         1 reject (small DeltaRSq)

RSq changed by less than 0.001 at 3 terms (DeltaRSq 0.00028)
After forward pass GRSq 0.992 RSq 0.996
Forward pass complete: 3 terms

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2      0.7964  0.8226     0.7964      1  1 2
chosen    3      0.9938  0.9954     0.1974      1  1 2 3

Prune backward penalty 2 nprune null: selected 3 of 3 terms, and 1 of 2 preds
After pruning pass GRSq 0.994 RSq 0.995
> a6  <- earth(new.x, Volume, wp=1, keepxy=TRUE)
> check.models.equal(a6update, a6, msg="a6update a6", newdata=newdata.global)
a6update a6: models identical

> 
> cat("\nupdate(a, wp=2)\n")

update(a, wp=2)
> a7update <- update(a, wp=2)
> a7  <- earth(x, Volume, wp=2, keepxy=TRUE)
> check.models.equal(a7update, a7, msg="a7update a7", newdata=newdata.global)
a7update a7: models identical

> 
> cat("--- beta cache -------------------------\n")
--- beta cache -------------------------
> 
> a1 <- earth(O3 ~ ., data = ozone1, degree = 3)
> a2 <- earth(O3 ~ ., data = ozone1, degree = 3, Use.beta.cache=FALSE)
> a1$call <- NULL
> a2$call <- NULL
> stopifnot(identical(a1, a2))
> 
> cat("--- test \"call\" printing in earth.default and summary.earth ---\n")
--- test "call" printing in earth.default and summary.earth ---
> # we want to make sure that long x or y aren't printed but short ones are
> 
> x = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+       0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+       0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+       0,1,2,3,4,5,6,7,8,9,0)
> 
> y = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+       0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+       0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+       0,1,2,3,4,5,6,7,8,9,0)
> 
> a <- earth(x = x, y=y, trace=5)
Call: earth(x=x, y=y, trace=5)

x[101,1]:
    x
1   0
2   1
3   2
4   3
5   4
6   5
7   6
8   7
9   8
10  9
11  0
12  1
13  2
14  3
15  4
16  5
17  6
18  7
19  8
20  9
21  0
22  1
23  2
24  3
25  4
26  5
27  6
28  7
29  8
30  9
31  0
32  1
33  2
34  3
35  4
36  5
37  6
38  7
39  8
40  9
41  0
42  1
43  2
44  3
45  4
46  5
47  6
48  7
49  8
50  9
51  0
52  1
53  2
54  3
55  4
56  5
57  6
58  7
59  8
60  9
61  0
62  1
63  2
64  3
65  4
66  5
67  6
68  7
69  8
70  9
71  0
72  1
73  2
74  3
75  4
76  5
77  6
78  7
79  8
80  9
81  0
82  1
83  2
84  3
85  4
86  5
87  6
88  7
89  8
90  9
91  0
92  1
93  2
94  3
95  4
96  5
97  6
98  7
99  8
100 9
101 0
       x        
 Min.   :0.000  
 1st Qu.:2.000  
 Median :4.000  
 Mean   :4.455  
 3rd Qu.:7.000  
 Max.   :9.000  

y[101,1]:
    y
1   0
2   1
3   2
4   3
5   4
6   5
7   6
8   7
9   8
10  9
11  0
12  1
13  2
14  3
15  4
16  5
17  6
18  7
19  8
20  9
21  0
22  1
23  2
24  3
25  4
26  5
27  6
28  7
29  8
30  9
31  0
32  1
33  2
34  3
35  4
36  5
37  6
38  7
39  8
40  9
41  0
42  1
43  2
44  3
45  4
46  5
47  6
48  7
49  8
50  9
51  0
52  1
53  2
54  3
55  4
56  5
57  6
58  7
59  8
60  9
61  0
62  1
63  2
64  3
65  4
66  5
67  6
68  7
69  8
70  9
71  0
72  1
73  2
74  3
75  4
76  5
77  6
78  7
79  8
80  9
81  0
82  1
83  2
84  3
85  4
86  5
87  6
88  7
89  8
90  9
91  0
92  1
93  2
94  3
95  4
96  5
97  6
98  7
99  8
100 9
101 0
       y        
 Min.   :0.000  
 1st Qu.:2.000  
 Median :4.000  
 Mean   :4.455  
 3rd Qu.:7.000  
 Max.   :9.000  

maxmem 0.0 GB

Scale.y = TRUE: yscale 2.907 ycenter 4.4554

yscaled[101,1]:
             y
1   -1.5326750
2   -1.1886746
3   -0.8446742
4   -0.5006738
5   -0.1566734
6    0.1873269
7    0.5313273
8    0.8753277
9    1.2193281
10   1.5633285
11  -1.5326750
12  -1.1886746
13  -0.8446742
14  -0.5006738
15  -0.1566734
16   0.1873269
17   0.5313273
18   0.8753277
19   1.2193281
20   1.5633285
21  -1.5326750
22  -1.1886746
23  -0.8446742
24  -0.5006738
25  -0.1566734
26   0.1873269
27   0.5313273
28   0.8753277
29   1.2193281
30   1.5633285
31  -1.5326750
32  -1.1886746
33  -0.8446742
34  -0.5006738
35  -0.1566734
36   0.1873269
37   0.5313273
38   0.8753277
39   1.2193281
40   1.5633285
41  -1.5326750
42  -1.1886746
43  -0.8446742
44  -0.5006738
45  -0.1566734
46   0.1873269
47   0.5313273
48   0.8753277
49   1.2193281
50   1.5633285
51  -1.5326750
52  -1.1886746
53  -0.8446742
54  -0.5006738
55  -0.1566734
56   0.1873269
57   0.5313273
58   0.8753277
59   1.2193281
60   1.5633285
61  -1.5326750
62  -1.1886746
63  -0.8446742
64  -0.5006738
65  -0.1566734
66   0.1873269
67   0.5313273
68   0.8753277
69   1.2193281
70   1.5633285
71  -1.5326750
72  -1.1886746
73  -0.8446742
74  -0.5006738
75  -0.1566734
76   0.1873269
77   0.5313273
78   0.8753277
79   1.2193281
80   1.5633285
81  -1.5326750
82  -1.1886746
83  -0.8446742
84  -0.5006738
85  -0.1566734
86   0.1873269
87   0.5313273
88   0.8753277
89   1.2193281
90   1.5633285
91  -1.5326750
92  -1.1886746
93  -0.8446742
94  -0.5006738
95  -0.1566734
96   0.1873269
97   0.5313273
98   0.8753277
99   1.2193281
100  1.5633285
101 -1.5326750
       y          
 Min.   :-1.5327  
 1st Qu.:-0.8447  
 Median :-0.1567  
 Mean   : 0.0000  
 3rd Qu.: 0.8753  
 Max.   : 1.5633  

earth.c version 5.3.4
BetaCache 3.45 kB
Forward pass: minspan 4 endspan 7   x[101,1] 808 Bytes   bx[101,21] 16.6 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      1.0000 1.0000            1    1            x           0< 2             1 final (max RSq)

Reached maximum RSq 0.9990 at 3 terms, 2 terms used (RSq 1.0000)
After forward pass GRSq 1.000 RSq 1.000
Forward pass complete: 3 terms, 2 terms used

Using EvalSubsetsUsingXtx (rather than leaps) because ncol(bx) <= 2
     nTerms iTerm    DeltaRss     RSq
          2     2      845.05 -0.0000 min

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
chosen    2      1.0000  1.0000     1.0000      1  1 2

Prune backward penalty 2 nprune null: selected 2 of 2 terms, and 1 of 1 preds
After pruning pass GRSq 1 RSq 1
> 
> a.longx  <- earth(x = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0),
+                   y=y,
+                   trace=4)
Call: earth(x=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...), y=y,
            trace=4)

x[101,1]:
    x
1   0
2   1
3   2
... 3
101 0

y[101,1]:
    y
1   0
2   1
3   2
... 3
101 0

Forward pass: minspan 4 endspan 7   x[101,1] 808 Bytes   bx[101,21] 16.6 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      1.0000 1.0000            1    1            x           0< 2             1 final (max RSq)

Reached maximum RSq 0.9990 at 3 terms, 2 terms used (RSq 1.0000)
After forward pass GRSq 1.000 RSq 1.000
Forward pass complete: 3 terms, 2 terms used

Using EvalSubsetsUsingXtx (rather than leaps) because ncol(bx) <= 2
     nTerms iTerm    DeltaRss     RSq
          2     2      845.05 -0.0000 min

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
chosen    2      1.0000  1.0000     1.0000      1  1 2

Prune backward penalty 2 nprune null: selected 2 of 2 terms, and 1 of 1 preds
After pruning pass GRSq 1 RSq 1
> 
> a.longy  <- earth(x = x,
+                   y = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0),
+                   trace=4)
Call: earth(x=x, y=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...),
            trace=4)

x[101,1]:
    x
1   0
2   1
3   2
... 3
101 0

y[101,1]:
    y
1   0
2   1
3   2
... 3
101 0

Forward pass: minspan 4 endspan 7   x[101,1] 808 Bytes   bx[101,21] 16.6 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      1.0000 1.0000            1    1            x           0< 2             1 final (max RSq)

Reached maximum RSq 0.9990 at 3 terms, 2 terms used (RSq 1.0000)
After forward pass GRSq 1.000 RSq 1.000
Forward pass complete: 3 terms, 2 terms used

Using EvalSubsetsUsingXtx (rather than leaps) because ncol(bx) <= 2
     nTerms iTerm    DeltaRss     RSq
          2     2      845.05 -0.0000 min

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
chosen    2      1.0000  1.0000     1.0000      1  1 2

Prune backward penalty 2 nprune null: selected 2 of 2 terms, and 1 of 1 preds
After pruning pass GRSq 1 RSq 1
> 
> a.longxy <- earth(x = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0),
+                   y = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+                         0,1,2,3,4,5,6,7,8,9,0),
+                   trace=4)
Call: earth(x=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...),
            y=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...), trace=4)

x[101,1]:
    x
1   0
2   1
3   2
... 3
101 0

y[101,1]:
    y
1   0
2   1
3   2
... 3
101 0

Forward pass: minspan 4 endspan 7   x[101,1] 808 Bytes   bx[101,21] 16.6 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      1.0000 1.0000            1    1            x           0< 2             1 final (max RSq)

Reached maximum RSq 0.9990 at 3 terms, 2 terms used (RSq 1.0000)
After forward pass GRSq 1.000 RSq 1.000
Forward pass complete: 3 terms, 2 terms used

Using EvalSubsetsUsingXtx (rather than leaps) because ncol(bx) <= 2
     nTerms iTerm    DeltaRss     RSq
          2     2      845.05 -0.0000 min

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
chosen    2      1.0000  1.0000     1.0000      1  1 2

Prune backward penalty 2 nprune null: selected 2 of 2 terms, and 1 of 1 preds
After pruning pass GRSq 1 RSq 1
> printh(summary(a))
===summary(a) 
Call: earth(x=x, y=y, trace=5)

             coefficients
(Intercept) -7.070164e-16
x            1.000000e+00

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: Reached maximum RSq 0.9990 at 2 terms
Importance: x
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> printh(summary(a.longx))
===summary(a.longx) 
Call: earth(x=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...), y=y,
            trace=4)

             coefficients
(Intercept) -7.070164e-16
x            1.000000e+00

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: Reached maximum RSq 0.9990 at 2 terms
Importance: x
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> printh(summary(a.longy))
===summary(a.longy) 
Call: earth(x=x, y=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...),
            trace=4)

             coefficients
(Intercept) -7.070164e-16
x            1.000000e+00

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: Reached maximum RSq 0.9990 at 2 terms
Importance: x
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> printh(summary(a.longxy))
===summary(a.longxy) 
Call: earth(x=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...),
            y=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...), trace=4)

             coefficients
(Intercept) -7.070164e-16
x            1.000000e+00

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: Reached maximum RSq 0.9990 at 2 terms
Importance: x
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> printh(summary(a.longxy, style="bf"))
===summary(a.longxy, style = "bf") 
Call: earth(x=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...),
            y=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,...), trace=4)

y =
  -7.070164e-16
  + 1 * bf1

   bf1  x

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: Reached maximum RSq 0.9990 at 2 terms
Importance: x
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> 
> cat("--- factors with x,y interface -------------------------\n")
--- factors with x,y interface -------------------------
> # this also tests for integer variables in the input matrix
> data(etitanic)
> attach(etitanic)
> a1 <- earth(pclass, sex, degree=2, trace=2)        # x=unordered y=unordered
x[1046,2] with colnames 2nd 3rd
y[1046,1] with colname male, and values 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,...
Forward pass: minspan 6 endspan 8   x[1046,2] 16.3 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0133 0.0180      0.01797    2          3rd           0< 2             1 
4      0.0116 0.0210     0.003025    1          2nd           0< 3             1 
6      0.0068 0.0210            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 5 terms, 3 terms used (DeltaRSq 0)
After forward pass GRSq 0.007 RSq 0.021
Forward pass complete: 5 terms, 3 terms used
Prune backward penalty 3 nprune null: selected 2 of 3 terms, and 1 of 2 preds
After pruning pass GRSq 0.0133 RSq 0.018
> printh(summary(a1))
===summary(a1) 
Call: earth(x=pclass, y=sex, trace=2, degree=2)

            coefficients
(Intercept)    0.5669725
3rd            0.1296343

Selected 2 of 3 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: 3rd, 2nd-unused
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0.2306901    RSS 239.6897    GRSq 0.01325722    RSq 0.01797283
> printh(summary(a1, style="bf"))
===summary(a1, style = "bf") 
Call: earth(x=pclass, y=sex, trace=2, degree=2)

male =
  0.5669725
  + 0.1296343 * bf1

   bf1  3rd

Selected 2 of 3 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: 3rd, 2nd-unused
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0.2306901    RSS 239.6897    GRSq 0.01325722    RSq 0.01797283
> if (PLOT)
+     plot(a1)
> a2 <- earth(sex, pclass, degree=2, trace=2)        # x=unordered y=unordered
x[1046,1] with colname male, and values 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,...
y[1046,3] with colnames 1st 2nd 3rd
Forward pass: minspan 5 endspan 7   x[1046,1] 8.17 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0073 0.0120      0.01202    1         male           0< 2             1 
4      0.0025 0.0120            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 3 terms, 2 terms used (DeltaRSq 0)
After forward pass GRSq 0.003 RSq 0.012
Forward pass complete: 3 terms, 2 terms used
Using EvalSubsetsUsingXtx (rather than leaps) because this is a multiple response model
Prune backward penalty 3 nprune null: selected 2 of 2 terms, and 1 of 1 preds
After pruning pass GRSq 0.00728 RSq 0.012
> printh(summary(a2))
===summary(a2) 
Call: earth(x=sex, y=pclass, trace=2, degree=2)

                   1st         2nd       3rd
(Intercept)  0.3427835  0.26546392 0.3917526
male        -0.1133002 -0.02534234 0.1386426

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: RSq changed by less than 0.001 at 2 terms
Importance: male
Number of terms at each degree of interaction: 1 1 (additive model)

          GCV      RSS         GRSq          RSq
1st 0.1961073 203.7578  0.010414990 0.0151441824
2nd 0.1883694 195.7180 -0.003997793 0.0008002778
3rd 0.2467207 256.3457  0.013257223 0.0179728324
All 0.6311974 655.8215  0.007279765 0.0120239411
> if (PLOT)
+     plot(a2, nresponse=1)
> a3 <- earth(pclass, age, degree=2, trace=2)        # x=unordered y=numeric
x[1046,2] with colnames 2nd 3rd
y[1046,1] with colname age, and values 29, 0.9167, 2, 30, 25, 48, 63...
Forward pass: minspan 6 endspan 8   x[1046,2] 16.3 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.1094 0.1136       0.1136    2          3rd           0< 2             1 
4      0.1640 0.1720      0.05838    1          2nd           0< 3             1 
6      0.1600 0.1720            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 5 terms, 3 terms used (DeltaRSq 0)
After forward pass GRSq 0.160 RSq 0.172
Forward pass complete: 5 terms, 3 terms used
Prune backward penalty 3 nprune null: selected 3 of 3 terms, and 2 of 2 preds
After pruning pass GRSq 0.164 RSq 0.172
> printh(summary(a3))
===summary(a3) 
Call: earth(x=pclass, y=age, trace=2, degree=2)

            coefficients
(Intercept)    39.159918
2nd            -9.653213
3rd           -14.343551

Selected 3 of 3 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: 3rd, 2nd
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 173.8417    RSS 179758.3    GRSq 0.1640128    RSq 0.1719935
> if (PLOT)
+     plot(a3, nresponse=1)
> a4 <- earth(age, pclass, degree=2, trace=2)        # x=numeric y=unordered
x[1046,1] with colname age, and values 29, 0.9167, 2, 30, 25, 48, 63...
y[1046,3] with colnames 1st 2nd 3rd
Forward pass: minspan 5 endspan 7   x[1046,1] 8.17 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0893 0.0980      0.09797    1          age          26  2   3         1 
4      0.0891 0.1021     0.004178    1          age          55  4             1 
6      0.0881 0.1055     0.003357    1          age          16  5             1 
8      0.0849 0.1067      0.00116    1          age          44  6             1 
10     0.0813 0.1075    0.0008104    1          age          48  7             1 reject (small DeltaRSq)

RSq changed by less than 0.001 at 9 terms, 6 terms used (DeltaRSq 0.00081)
After forward pass GRSq 0.081 RSq 0.107
Forward pass complete: 9 terms, 6 terms used
Using EvalSubsetsUsingXtx (rather than leaps) because this is a multiple response model
Prune backward penalty 3 nprune null: selected 2 of 6 terms, and 1 of 1 preds
After pruning pass GRSq 0.093 RSq 0.0974
> printh(summary(a4))
===summary(a4) 
Call: earth(x=age, y=pclass, trace=2, degree=2)

                   1st           2nd         3rd
(Intercept) 0.06439450  0.2563335580  0.67927195
h(age-16)   0.01388561 -0.0004566659 -0.01342895

Selected 2 of 6 terms, and 1 of 1 predictors
Termination condition: RSq changed by less than 0.001 at 6 terms
Importance: age
Number of terms at each degree of interaction: 1 1 (additive model)

          GCV      RSS         GRSq        RSq
1st 0.1670033 173.5184  0.157277818 0.16130516
2nd 0.1884855 195.8387 -0.004616749 0.00018428
3rd 0.2211945 229.8237  0.115347486 0.11957521
All 0.5766834 599.1808  0.093017132 0.09735157
> if (PLOT)
+     plot(a4, nresponse=1)
> a5 <- earth(etitanic[,c(2:4)], pclass, degree=2, trace=2)  # x=mixed  y=unordered
x[1046,3] with colnames survived sexmale age
y[1046,3] with colnames 1st 2nd 3rd
Forward pass: minspan 6 endspan 8   x[1046,3] 24.5 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0893 0.0980      0.09797    3          age          26  2   3         1 
4      0.1500 0.1622       0.0642    1     survived           0< 4             1 
6      0.1557 0.1758      0.01364    3          age          16  5   6     4   2 
8      0.1603 0.1842     0.008445    2      sexmale           0< 7         4   2 
10     0.1631 0.1909     0.006652    2      sexmale           0< 8             1 
12     0.1616 0.1934      0.00253    3          age          57  9             1 
14     0.1599 0.1956     0.002212    2      sexmale           0< 10        2   2 
16     0.1541 0.1980     0.002352    3          age           5  11  12   10   2 
18     0.1529 0.2008     0.002846    3          age           2  13            1 
20     0.1495 0.2016    0.0007302    3          age          12  14        4   2 reject (small DeltaRSq)

RSq changed by less than 0.001 at 19 terms, 13 terms used (DeltaRSq 0.00073)
After forward pass GRSq 0.149 RSq 0.202
Forward pass complete: 19 terms, 13 terms used
Using EvalSubsetsUsingXtx (rather than leaps) because this is a multiple response model
Prune backward penalty 3 nprune null: selected 7 of 13 terms, and 3 of 3 preds
After pruning pass GRSq 0.165 RSq 0.189
> printh(summary(a5))
===summary(a5) 
Call: earth(x=etitanic[,c(2:4)], y=pclass, trace=2, degree=2)

                             1st          2nd         3rd
(Intercept)          -0.02151789  0.210092649  0.81142524
survived              0.36119246  0.144874864 -0.50606732
sexmale               0.07967096  0.115755401 -0.19542636
h(26-age)            -0.00070712 -0.013836973  0.01454409
h(age-26)             0.01592910 -0.003659393 -0.01226971
survived * sexmale   -0.07745396 -0.293062401  0.37051636
survived * h(16-age) -0.02037404  0.038860933 -0.01848689

Selected 7 of 13 terms, and 3 of 3 predictors
Termination condition: RSq changed by less than 0.001 at 13 terms
Importance: age, survived, sexmale
Number of terms at each degree of interaction: 1 4 2

          GCV      RSS       GRSq        RSq
1st 0.1502539 152.3942 0.24179781 0.26340816
2nd 0.1834402 186.0532 0.02227456 0.05014178
3rd 0.1970609 199.8680 0.21186826 0.23433166
All 0.5307550 538.3155 0.16525132 0.18904341
> if (PLOT)
+     plot(a5, nresponse=1)
> a6 <- earth(etitanic[,c(1,3,4,5,6)], survived, degree=2, trace=2)  # x=mixed y=unordered
x[1046,6] with colnames pclass2nd pclass3rd sexmale age sibsp parch
y[1046,1] with colname survived, and values 1, 1, 0, 0, 0, 1, 1, 0, 1, 0,...
Forward pass: minspan 6 endspan 9   x[1046,6] 49 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.2860 0.2894       0.2894    3      sexmale           0< 2             1 
4      0.3297 0.3361      0.04669    2    pclass3rd           0< 3             1 
6      0.3588 0.3710      0.03488    4          age          16  4   5     2   2 
8      0.3962 0.4106      0.03954    1    pclass2nd           0< 6         2   2 
10     0.4143 0.4338       0.0232    5        sibsp           4  7   8     4   2 
12     0.4133 0.4383     0.004574    6        parch           1  9   10        1 
14     0.4150 0.4427      0.00437    2    pclass3rd           0< 11        2   2 
16     0.4116 0.4449     0.002169    5        sibsp           1  12  13    2   2 
18     0.4087 0.4477     0.002807    4          age          17  14  15   13   2 
20     0.4056 0.4502     0.002549    4          age          32  16  17        1 final (reached nk 21)

Reached nk 21
After forward pass GRSq 0.406 RSq 0.450
Forward pass complete: 21 terms, 17 terms used
Prune backward penalty 3 nprune null: selected 8 of 17 terms, and 5 of 6 preds
After pruning pass GRSq 0.42 RSq 0.439
> printh(summary(a6))
===summary(a6) 
Call: earth(x=etitanic[,c(1,3,4,5,6)], y=survived, trace=2, degree=2)

                       coefficients
(Intercept)              0.96170950
pclass3rd               -0.81545352
sexmale                 -0.57003496
h(age-32)               -0.00471938
pclass2nd * sexmale     -0.26568920
pclass3rd * sexmale      0.19310203
pclass3rd * h(4-sibsp)   0.10222181
sexmale * h(16-age)      0.04505232

Selected 8 of 17 terms, and 5 of 6 predictors
Termination condition: Reached nk 21
Importance: sexmale, pclass3rd, pclass2nd, age, sibsp, parch-unused
Number of terms at each degree of interaction: 1 3 4
GCV 0.1404529    RSS 141.7629    GRSq 0.4197106    RSq 0.4389834
> if (PLOT)
+     plot(a6)
> a7 <- earth(etitanic[,c(2,3,5,6)], etitanic[,c(1,4)], degree=2, trace=2)  # x=mixed y=mixed
x[1046,4] with colnames survived sexmale sibsp parch
y[1046,4] with colnames pclass1st pclass2nd pclass3rd age
Forward pass: minspan 6 endspan 9   x[1046,4] 32.7 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0813 0.0901      0.09011    4        parch           2  2   3         1 
4      0.1049 0.1219      0.03183    3        sibsp           1  4   5         1 
6      0.1068 0.1323      0.01034    4        parch           1  6   7     4   2 
8      0.1089 0.1385     0.006171    4        parch           4  8             1 
10     0.1093 0.1431      0.00463    3        sibsp           2  9             1 
12     0.1043 0.1466     0.003515    4        parch           1  10  11    5   2 
14     0.1024 0.1491     0.002463    2      sexmale           0< 12        3   2 
16     0.0998 0.1507     0.001651    1     survived           0< 13        4   2 
18     0.0974 0.1526     0.001929    1     survived           0< 14       10   2 
20     0.0944 0.1540     0.001385    4        parch           1  15            1 final (reached nk 21)

Reached nk 21
After forward pass GRSq 0.094 RSq 0.154
Forward pass complete: 21 terms, 15 terms used
Using EvalSubsetsUsingXtx (rather than leaps) because this is a multiple response model
Prune backward penalty 3 nprune null: selected 7 of 15 terms, and 2 of 4 preds
After pruning pass GRSq 0.113 RSq 0.138
> printh(summary(a7))
===summary(a7) 
Call: earth(x=etitanic[,c(2,3,5,6)], y=etitanic[,c(1,4)], trace=2, degree=2)

                          pclass1st   pclass2nd   pclass3rd        age
(Intercept)              0.36758408  0.35266924  0.27974668  22.291896
h(sibsp-1)              -0.12882542 -0.08036041  0.20918583  -7.715668
h(2-parch)              -0.04851620 -0.05326897  0.10178517   4.853565
h(parch-2)              -0.03888370 -0.12184854  0.16073223  13.049389
h(parch-4)              -0.16812822  0.04401127  0.12411695 -18.899871
h(sibsp-1) * h(parch-1)  0.05211343 -0.02136815 -0.03074529   4.418743
h(sibsp-1) * h(1-parch)  0.06525217  0.09912874 -0.16438091   7.403960

Selected 7 of 15 terms, and 2 of 4 predictors
Termination condition: Reached nk 21
Importance: sibsp, parch, survived-unused, sexmale-unused
Number of terms at each degree of interaction: 1 4 2

                 GCV        RSS        GRSq        RSq
pclass1st   0.200320    203.173 -0.01084030 0.01797077
pclass2nd   0.189624    192.326 -0.01068680 0.01811990
pclass3rd   0.243908    247.383  0.02450493 0.05230858
age       184.482965 187110.877  0.11283993 0.13812585
All       185.116817 187753.758  0.11250542 0.13780087
> if (PLOT)
+     plot(a7, nresponse=1)
> 
> cat("--- factors with formula interface -------------------------\n")
--- factors with formula interface -------------------------
> # these correspond to the models above (except a7 which is a multiple response model)
> a1f <- earth(sex ~ pclass, degree=2, trace=2)        # x=unordered y=unordered
x[1046,2] with colnames pclass2nd pclass3rd
y[1046,1] with colname male, and values 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,...
Forward pass: minspan 6 endspan 8   x[1046,2] 16.3 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0133 0.0180      0.01797    2    pclass3rd           0< 2             1 
4      0.0116 0.0210     0.003025    1    pclass2nd           0< 3             1 
6      0.0068 0.0210            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 5 terms, 3 terms used (DeltaRSq 0)
After forward pass GRSq 0.007 RSq 0.021
Forward pass complete: 5 terms, 3 terms used
Prune backward penalty 3 nprune null: selected 2 of 3 terms, and 1 of 2 preds
After pruning pass GRSq 0.0133 RSq 0.018
> printh(summary(a1f))
===summary(a1f) 
Call: earth(formula=sex~pclass, trace=2, degree=2)

            coefficients
(Intercept)    0.5669725
pclass3rd      0.1296343

Selected 2 of 3 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: pclass3rd, pclass2nd-unused
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0.2306901    RSS 239.6897    GRSq 0.01325722    RSq 0.01797283
> printh(summary(a1f, style="bf"))
===summary(a1f, style = "bf") 
Call: earth(formula=sex~pclass, trace=2, degree=2)

male =
  0.5669725
  + 0.1296343 * bf1

   bf1  pclass3rd

Selected 2 of 3 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: pclass3rd, pclass2nd-unused
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0.2306901    RSS 239.6897    GRSq 0.01325722    RSq 0.01797283
> if (PLOT)
+     plot(a1f)
> a2f <- earth(pclass ~ sex, degree=2, trace=2)        # x=unordered y=unordered
x[1046,1] with colname sexmale, and values 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,...
y[1046,3] with colnames 1st 2nd 3rd
Forward pass: minspan 5 endspan 7   x[1046,1] 8.17 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0073 0.0120      0.01202    1      sexmale           0< 2             1 
4      0.0025 0.0120            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 3 terms, 2 terms used (DeltaRSq 0)
After forward pass GRSq 0.003 RSq 0.012
Forward pass complete: 3 terms, 2 terms used
Using EvalSubsetsUsingXtx (rather than leaps) because this is a multiple response model
Prune backward penalty 3 nprune null: selected 2 of 2 terms, and 1 of 1 preds
After pruning pass GRSq 0.00728 RSq 0.012
> printh(summary(a2f))
===summary(a2f) 
Call: earth(formula=pclass~sex, trace=2, degree=2)

                   1st         2nd       3rd
(Intercept)  0.3427835  0.26546392 0.3917526
sexmale     -0.1133002 -0.02534234 0.1386426

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: RSq changed by less than 0.001 at 2 terms
Importance: sexmale
Number of terms at each degree of interaction: 1 1 (additive model)

          GCV      RSS         GRSq          RSq
1st 0.1961073 203.7578  0.010414990 0.0151441824
2nd 0.1883694 195.7180 -0.003997793 0.0008002778
3rd 0.2467207 256.3457  0.013257223 0.0179728324
All 0.6311974 655.8215  0.007279765 0.0120239411
> if (PLOT)
+     plot(a2f, nresponse=1)
> a3f <- earth(age ~ pclass, degree=2, trace=2)        # x=unordered y=numeric
x[1046,2] with colnames pclass2nd pclass3rd
y[1046,1] with colname age, and values 29, 0.9167, 2, 30, 25, 48, 63...
Forward pass: minspan 6 endspan 8   x[1046,2] 16.3 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.1094 0.1136       0.1136    2    pclass3rd           0< 2             1 
4      0.1640 0.1720      0.05838    1    pclass2nd           0< 3             1 
6      0.1600 0.1720            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 5 terms, 3 terms used (DeltaRSq 0)
After forward pass GRSq 0.160 RSq 0.172
Forward pass complete: 5 terms, 3 terms used
Prune backward penalty 3 nprune null: selected 3 of 3 terms, and 2 of 2 preds
After pruning pass GRSq 0.164 RSq 0.172
> printh(summary(a3f))
===summary(a3f) 
Call: earth(formula=age~pclass, trace=2, degree=2)

            coefficients
(Intercept)    39.159918
pclass2nd      -9.653213
pclass3rd     -14.343551

Selected 3 of 3 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: pclass3rd, pclass2nd
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 173.8417    RSS 179758.3    GRSq 0.1640128    RSq 0.1719935
> if (PLOT)
+     plot(a3f)
> a4f <- earth(pclass ~ age, degree=2, trace=2)        # x=numeric y=unordered
x[1046,1] with colname age, and values 29, 0.9167, 2, 30, 25, 48, 63...
y[1046,3] with colnames 1st 2nd 3rd
Forward pass: minspan 5 endspan 7   x[1046,1] 8.17 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0893 0.0980      0.09797    1          age          26  2   3         1 
4      0.0891 0.1021     0.004178    1          age          55  4             1 
6      0.0881 0.1055     0.003357    1          age          16  5             1 
8      0.0849 0.1067      0.00116    1          age          44  6             1 
10     0.0813 0.1075    0.0008104    1          age          48  7             1 reject (small DeltaRSq)

RSq changed by less than 0.001 at 9 terms, 6 terms used (DeltaRSq 0.00081)
After forward pass GRSq 0.081 RSq 0.107
Forward pass complete: 9 terms, 6 terms used
Using EvalSubsetsUsingXtx (rather than leaps) because this is a multiple response model
Prune backward penalty 3 nprune null: selected 2 of 6 terms, and 1 of 1 preds
After pruning pass GRSq 0.093 RSq 0.0974
> printh(summary(a4f))
===summary(a4f) 
Call: earth(formula=pclass~age, trace=2, degree=2)

                   1st           2nd         3rd
(Intercept) 0.06439450  0.2563335580  0.67927195
h(age-16)   0.01388561 -0.0004566659 -0.01342895

Selected 2 of 6 terms, and 1 of 1 predictors
Termination condition: RSq changed by less than 0.001 at 6 terms
Importance: age
Number of terms at each degree of interaction: 1 1 (additive model)

          GCV      RSS         GRSq        RSq
1st 0.1670033 173.5184  0.157277818 0.16130516
2nd 0.1884855 195.8387 -0.004616749 0.00018428
3rd 0.2211945 229.8237  0.115347486 0.11957521
All 0.5766834 599.1808  0.093017132 0.09735157
> if (PLOT)
+     plot(a4f, nresponse=1)
> a5f <- earth(pclass ~ survived + sex + age, data=etitanic, degree=2, trace=2)  # x=mixed y=unordered
x[1046,3] with colnames survived sexmale age
y[1046,3] with colnames 1st 2nd 3rd
Forward pass: minspan 6 endspan 8   x[1046,3] 24.5 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0893 0.0980      0.09797    3          age          26  2   3         1 
4      0.1500 0.1622       0.0642    1     survived           0< 4             1 
6      0.1557 0.1758      0.01364    3          age          16  5   6     4   2 
8      0.1603 0.1842     0.008445    2      sexmale           0< 7         4   2 
10     0.1631 0.1909     0.006652    2      sexmale           0< 8             1 
12     0.1616 0.1934      0.00253    3          age          57  9             1 
14     0.1599 0.1956     0.002212    2      sexmale           0< 10        2   2 
16     0.1541 0.1980     0.002352    3          age           5  11  12   10   2 
18     0.1529 0.2008     0.002846    3          age           2  13            1 
20     0.1495 0.2016    0.0007302    3          age          12  14        4   2 reject (small DeltaRSq)

RSq changed by less than 0.001 at 19 terms, 13 terms used (DeltaRSq 0.00073)
After forward pass GRSq 0.149 RSq 0.202
Forward pass complete: 19 terms, 13 terms used
Using EvalSubsetsUsingXtx (rather than leaps) because this is a multiple response model
Prune backward penalty 3 nprune null: selected 7 of 13 terms, and 3 of 3 preds
After pruning pass GRSq 0.165 RSq 0.189
> printh(summary(a5f))
===summary(a5f) 
Call: earth(formula=pclass~survived+sex+age, data=etitanic, trace=2, degree=2)

                             1st          2nd         3rd
(Intercept)          -0.02151789  0.210092649  0.81142524
survived              0.36119246  0.144874864 -0.50606732
sexmale               0.07967096  0.115755401 -0.19542636
h(26-age)            -0.00070712 -0.013836973  0.01454409
h(age-26)             0.01592910 -0.003659393 -0.01226971
survived * sexmale   -0.07745396 -0.293062401  0.37051636
survived * h(16-age) -0.02037404  0.038860933 -0.01848689

Selected 7 of 13 terms, and 3 of 3 predictors
Termination condition: RSq changed by less than 0.001 at 13 terms
Importance: age, survived, sexmale
Number of terms at each degree of interaction: 1 4 2

          GCV      RSS       GRSq        RSq
1st 0.1502539 152.3942 0.24179781 0.26340816
2nd 0.1834402 186.0532 0.02227456 0.05014178
3rd 0.1970609 199.8680 0.21186826 0.23433166
All 0.5307550 538.3155 0.16525132 0.18904341
> if (PLOT)
+     plot(a5f, nresponse=1)
> a6f <- earth(survived ~ ., data=etitanic, degree=2, trace=2)  # x=mixed y=unordered
x[1046,6] with colnames pclass2nd pclass3rd sexmale age sibsp parch
y[1046,1] with colname survived, and values 1, 1, 0, 0, 0, 1, 1, 0, 1, 0,...
Forward pass: minspan 6 endspan 9   x[1046,6] 49 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.2860 0.2894       0.2894    3      sexmale           0< 2             1 
4      0.3297 0.3361      0.04669    2    pclass3rd           0< 3             1 
6      0.3588 0.3710      0.03488    4          age          16  4   5     2   2 
8      0.3962 0.4106      0.03954    1    pclass2nd           0< 6         2   2 
10     0.4143 0.4338       0.0232    5        sibsp           4  7   8     4   2 
12     0.4133 0.4383     0.004574    6        parch           1  9   10        1 
14     0.4150 0.4427      0.00437    2    pclass3rd           0< 11        2   2 
16     0.4116 0.4449     0.002169    5        sibsp           1  12  13    2   2 
18     0.4087 0.4477     0.002807    4          age          17  14  15   13   2 
20     0.4056 0.4502     0.002549    4          age          32  16  17        1 final (reached nk 21)

Reached nk 21
After forward pass GRSq 0.406 RSq 0.450
Forward pass complete: 21 terms, 17 terms used
Prune backward penalty 3 nprune null: selected 8 of 17 terms, and 5 of 6 preds
After pruning pass GRSq 0.42 RSq 0.439
> printh(summary(a6f))
===summary(a6f) 
Call: earth(formula=survived~., data=etitanic, trace=2, degree=2)

                       coefficients
(Intercept)              0.96170950
pclass3rd               -0.81545352
sexmale                 -0.57003496
h(age-32)               -0.00471938
pclass2nd * sexmale     -0.26568920
pclass3rd * sexmale      0.19310203
pclass3rd * h(4-sibsp)   0.10222181
sexmale * h(16-age)      0.04505232

Selected 8 of 17 terms, and 5 of 6 predictors
Termination condition: Reached nk 21
Importance: sexmale, pclass3rd, pclass2nd, age, sibsp, parch-unused
Number of terms at each degree of interaction: 1 3 4
GCV 0.1404529    RSS 141.7629    GRSq 0.4197106    RSq 0.4389834
> if (PLOT)
+     plot(a6f)
> detach(etitanic)
> 
> # basic test with ordered factors
> # TODO June 2021: this doesn't actually check factors and never has, see note below
> ff <- factor(substring("statistics", 1:10, 1:10), levels=letters, ordered=TRUE)
> # NOTE: Jun 2021: added as.numeric for backward compability with R pre version R 4.1.0
> ff <- as.numeric(c(ff, ff, ff))
> vowels = (ff == 1 | ff == 9) * 3
> printh(head(ff))
===head(ff) 
[1] 19 20  1 20  9 19
> printh(head(vowels))
===head(vowels) 
[1] 0 0 3 0 3 0
> a8 <- earth(ff, vowels, degree=1, trace=2)        # x=ordered y=numeric
x[30,1] with colname ff, and values 19, 20, 1, 20, 9, 19, 20, 9, ...
y[30,1] with colname vowels, and values 0, 0, 3, 0, 3, 0, 0, 3, 0, 0,...
Forward pass: minspan 3 endspan 7   x[30,1] 240 Bytes   bx[30,21] 4.92 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.5906 0.6958       0.6958    1           ff           9  2   3         1 
4      0.5250 0.7012     0.005454    1           ff          19  4             1 
6      0.4302 0.7012            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 5 terms, 4 terms used (DeltaRSq 0)
After forward pass GRSq 0.430 RSq 0.701
Forward pass complete: 5 terms, 4 terms used
Prune backward penalty 2 nprune null: selected 3 of 4 terms, and 1 of 1 preds
After pruning pass GRSq 0.591 RSq 0.696
> printh(summary(a8))
===summary(a8) 
Call: earth(x=ff, y=vowels, trace=2, degree=1)

            coefficients
(Intercept)    2.7464305
h(9-ff)       -0.1445003
h(ff-9)       -0.2609730

Selected 3 of 4 terms, and 1 of 1 predictors
Termination condition: RSq changed by less than 0.001 at 4 terms
Importance: ff
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 0.828019    RSS 17.2504    GRSq 0.5906149    RSq 0.6957602
> if (PLOT)
+     plot(a8, nresponse=1)
> plotmo(a8, caption="a8", pt.col=3)
Warning: Cannot determine which variables to plot (use all1=TRUE?)
             single.names=c(ff,ff)
             colnames(x)=x

> a9 <- earth(vowels, ff, degree=1, trace=2)        # x=numeric y=ordered
x[30,1] with colname vowels, and values 0, 0, 3, 0, 3, 0, 0, 3, 0, 0,...
y[30,1] with colname ff, and values 19, 20, 1, 20, 9, 19, 20, 9, ...
Forward pass: minspan 3 endspan 7   x[30,1] 240 Bytes   bx[30,21] 4.92 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.3877 0.4693       0.4693    1       vowels           0< 2             1 
4      0.2858 0.4693            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 3 terms, 2 terms used (DeltaRSq 0)
After forward pass GRSq 0.286 RSq 0.469
Forward pass complete: 3 terms, 2 terms used
Using EvalSubsetsUsingXtx (rather than leaps) because ncol(bx) <= 2
Prune backward penalty 2 nprune null: selected 2 of 2 terms, and 1 of 1 preds
After pruning pass GRSq 0.388 RSq 0.469
> if (PLOT)
+     plot(a9, nresponse=1)
> printh(summary(a9))
===summary(a9) 
Call: earth(x=vowels, y=ff, trace=2, degree=1)

            coefficients
(Intercept)    17.142857
vowels         -3.603175

Selected 2 of 2 terms, and 1 of 1 predictors
Termination condition: RSq changed by less than 0.001 at 2 terms
Importance: vowels
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 34.2622    RSS 832.5714    GRSq 0.38772    RSq 0.4692603
> 
> cat("--- wp argument---------------------------------\n")
--- wp argument---------------------------------
> set.seed(79)
> NWP <- 100
> x1 <- runif(NWP)
> x2 <- runif(NWP)
> y1 <- (x1 > .5) + .3 * runif(1)
> y2 <- sin(3 * x2) + .3 * runif(1)
> myw <- 10
> m <- mars(cbind(x1,x2), cbind(y1, y2))
> me1 <- mars.to.earth(m)
Converted mars(x=cbind(x1,x2), y=cbind(y1,y2))

to earth(x=cbind(x1,x2), y=cbind(y1,y2))

> printh(me1)
===me1 
Selected 7 of 13 terms, and 2 of 2 predictors
Termination condition: Unknown
Importance: object has no prune.terms, call update() on the model to fix that
Number of terms at each degree of interaction: 1 6 (additive model)

             GCV        RSS      GRSq       RSq
y1  0.0212617234 1.60929985 0.9166455 0.9356280
y2  0.0006116807 0.04629811 0.9940111 0.9953750
All 0.0218734041 1.65559796 0.9390624 0.9529398
> e1 <- earth(cbind(x1,x2), cbind(y1, y2))
> printh(e1)
===e1 
Selected 7 of 9 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 9 terms
Importance: x1, x2
Number of terms at each degree of interaction: 1 6 (additive model)

             GCV        RSS      GRSq       RSq
y1  0.0252890017 1.91412454 0.9008570 0.9234350
y2  0.0007586223 0.05742013 0.9925725 0.9942639
All 0.0260476241 1.97154466 0.9270808 0.9436868
> e2 <- earth(cbind(x1,x2), cbind(y1, y2),  wp=c(1,1))
> printh(e2)
===e2 
Selected 7 of 9 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 9 terms
Importance: x1, x2
Number of terms at each degree of interaction: 1 6 (additive model)

             GCV        RSS      GRSq       RSq
y1  0.0252890017 1.91412454 0.9008570 0.9234350
y2  0.0007586223 0.05742013 0.9925725 0.9942639
All 0.0260476241 1.97154466 0.9270808 0.9436868
> e1$call <- NULL
> e2$call <- NULL
> e1$wp <- NULL
> e2$wp <- NULL
> stopifnot(identical(e1, e2))
> e3 <- earth(cbind(x1,x2), cbind(y1, y2),  wp=c(.001,1))
> printh(e3)
===e3 
Selected 6 of 7 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 7 terms
Importance: x2, x1
Number of terms at each degree of interaction: 1 5 (additive model)

            GCV       RSS      GRSq       RSq
y1  0.058039265 4.5972902 0.7724629 0.8161084
y2  0.000297713 0.0235818 0.9970851 0.9976443
All 0.000710793 0.0563019 0.9965256 0.9971920
> wp <- c(1, 2)
> e3 <- earth(cbind(x1,x2), cbind(y1, y2),  wp=wp)
> printh(e3)
===e3 
Selected 7 of 9 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 9 terms
Importance: x1, x2
Number of terms at each degree of interaction: 1 6 (additive model)

             GCV        RSS      GRSq       RSq
y1  0.0252890017 1.91412454 0.9008570 0.9234350
y2  0.0007586223 0.05742013 0.9925725 0.9942639
All 0.0178708309 1.35264319 0.9416429 0.9549327
> m3 <- mars(cbind(x1,x2), cbind(y1, y2),  wp=wp)
> cat("response weights: wp", wp, "earth gcv", e3$gcv,
+     "mars gcv", m3$gcv, "mars gcv*length(wp)",
+     m3$gcv * length(wp), "\n")
response weights: wp 1 2 earth gcv 0.01787083 mars gcv 0.007495028 mars gcv*length(wp) 0.01499006 
> 
> expect.err(try(earth(cbind(O3, O3) ~ ., data=ozone1, wp=c(1, .01))),
+            "Duplicate colname in cbind(O3, O3) (colnames are \"O3\", \"O3\")")
Error : Duplicate colname in cbind(O3, O3) (colnames are "O3", "O3")
Got expected error from try(earth(cbind(O3, O3) ~ ., data = ozone1, wp = c(1, 0.01)))
> 
> oz2 <- ozone1
> oz2$O3a <- ozone1$O3
> e4 <- earth(cbind(O3, O3a) ~ ., data=oz2, wp=c(1, .01))
> printh(e4) # both sub models should be the same
===e4 
Selected 12 of 20 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, dpg, doy, vh, vis, ibt, ibh, wind
Number of terms at each degree of interaction: 1 11 (additive model)

         GCV      RSS      GRSq       RSq
O3  14.61004 4172.671 0.7730502 0.8023874
O3a 14.61004 4172.671 0.7730502 0.8023874
All 29.22008 8345.342 0.7730502 0.8023874
> printh(summary(e4))
===summary(e4) 
Call: earth(formula=cbind(O3,O3a)~., data=oz2, wp=c(1,0.01))

                       O3        O3a
(Intercept)    14.1595171 14.1595171
h(5860-vh)     -0.0137728 -0.0137728
h(wind-3)      -0.3377222 -0.3377222
h(54-humidity) -0.1349547 -0.1349547
h(temp-58)      0.2791320  0.2791320
h(1105-ibh)    -0.0033837 -0.0033837
h(dpg-10)      -0.0991581 -0.0991581
h(ibt-120)      0.0326330  0.0326330
h(150-vis)      0.0231881  0.0231881
h(96-doy)      -0.1105145 -0.1105145
h(doy-96)       0.0406468  0.0406468
h(doy-158)     -0.0836732 -0.0836732

Selected 12 of 20 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, dpg, doy, vh, vis, ibt, ibh, wind
Number of terms at each degree of interaction: 1 11 (additive model)

         GCV      RSS      GRSq       RSq
O3  14.61004 4172.671 0.7730502 0.8023874
O3a 14.61004 4172.671 0.7730502 0.8023874
All 29.22008 8345.342 0.7730502 0.8023874
> 
> # wp with formula interface
> e5 <- earth(cbind(O3, wind) ~ ., data=ozone1, wp=c(1, 1))
> printh(e5)
===e5 
Selected 12 of 19 terms, and 8 of 8 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, dpg, doy, vh, vis, ibh, ibt
Number of terms at each degree of interaction: 1 11 (additive model)

           GCV       RSS      GRSq       RSq
O3   14.902776 4256.2781 0.7685029 0.7984278
wind  3.488862  996.4297 0.2238615 0.3241907
All  18.391639 5252.7078 0.7329545 0.7674747
> printh(summary(e5))
===summary(e5) 
Call: earth(formula=cbind(O3,wind)~., data=ozone1, wp=c(1,1))

                       O3       wind
(Intercept)    10.5988809  5.6114349
h(5610-vh)     -0.0201264  0.0125912
h(vh-5610)      0.0181809 -0.0060755
h(54-humidity) -0.1506629  0.0119373
h(temp-56)      0.2646075  0.0550381
h(1105-ibh)    -0.0034196 -0.0008298
h(dpg-13)      -0.0954378  0.0046173
h(ibt-120)      0.0336582 -0.0045594
h(150-vis)      0.0217267 -0.0006158
h(96-doy)      -0.1307894 -0.0090201
h(doy-158)     -0.0418477  0.0043672
h(doy-312)      0.0359320 -0.0570514

Selected 12 of 19 terms, and 8 of 8 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, dpg, doy, vh, vis, ibh, ibt
Number of terms at each degree of interaction: 1 11 (additive model)

           GCV       RSS      GRSq       RSq
O3   14.902776 4256.2781 0.7685029 0.7984278
wind  3.488862  996.4297 0.2238615 0.3241907
All  18.391639 5252.7078 0.7329545 0.7674747
> e5 <- earth(cbind(O3, wind) ~ ., data=ozone1, wp=c(.3, 1))
> printh(e5)
===e5 
Selected 11 of 19 terms, and 7 of 8 predictors
Termination condition: Reached nk 21
Importance: temp, ibh, doy, humidity, dpg, vh, vis, ibt-unused
Number of terms at each degree of interaction: 1 10 (additive model)

           GCV       RSS      GRSq       RSq
O3   15.271877 4418.7094 0.7627693 0.7907353
wind  3.410203  986.6958 0.2413602 0.3307925
All  12.295025 3557.3978 0.6643222 0.7038936
> printh(summary(e5))
===summary(e5) 
Call: earth(formula=cbind(O3,wind)~., data=ozone1, wp=c(0.3,1))

                       O3       wind
(Intercept)     7.4506335  4.6371421
h(5610-vh)     -0.0141304  0.0118244
h(vh-5610)      0.0175637 -0.0038642
h(humidity-23)  0.0838361  0.0071938
h(temp-55)      0.3675094  0.0292957
h(ibh-1105)    -0.0004039  0.0002864
h(dpg-13)      -0.0862256  0.0011425
h(150-vis)      0.0197846 -0.0005190
h(96-doy)      -0.1367936 -0.0089124
h(doy-150)     -0.0391186  0.0036656
h(doy-294)      0.0273699 -0.0421686

Selected 11 of 19 terms, and 7 of 8 predictors
Termination condition: Reached nk 21
Importance: temp, ibh, doy, humidity, dpg, vh, vis, ibt-unused
Number of terms at each degree of interaction: 1 10 (additive model)

           GCV       RSS      GRSq       RSq
O3   15.271877 4418.7094 0.7627693 0.7907353
wind  3.410203  986.6958 0.2413602 0.3307925
All  12.295025 3557.3978 0.6643222 0.7038936
> # wp with factors
> e6 <- earth(pclass ~ ., data=etitanic, degree=2, wp=c(.001,.001,1))
> printh(e6)
===e6 
Selected 9 of 18 terms, and 5 of 5 predictors
Termination condition: Reached nk 21
Importance: age, survived, sexmale, sibsp, parch
Number of terms at each degree of interaction: 1 5 3

          GCV      RSS      GRSq        RSq
1st 0.1498185 150.4809 0.2439951 0.27265613
2nd 0.1876176 188.4472 0.0000000 0.03791987
3rd 0.1888766 189.7117 0.2446010 0.27323905
All 0.5665090 569.0139 0.2444172 0.27306228
> printh(summary(e6))
===summary(e6) 
Call: earth(formula=pclass~., data=etitanic, wp=c(0.001,0.001,1), degree=2)

                                1st          2nd         3rd
(Intercept)            -0.013576232  0.282485118  0.73109111
survived                0.312918412  0.174952174 -0.48787059
sexmale                 0.073351259  0.149478916 -0.22283017
h(age-9)                0.011822473 -0.003165402 -0.00865707
h(1-sibsp)             -0.090396669 -0.045506746  0.13590342
h(parch-2)             -0.120345986 -0.075313793  0.19565978
survived * sexmale     -0.077447025 -0.291809662  0.36925669
h(21-age) * h(sibsp-1) -0.001063853 -0.008028212  0.00909206
h(57-age) * h(2-parch) -0.001527820 -0.001150068  0.00267789

Selected 9 of 18 terms, and 5 of 5 predictors
Termination condition: Reached nk 21
Importance: age, survived, sexmale, sibsp, parch
Number of terms at each degree of interaction: 1 5 3

          GCV      RSS      GRSq        RSq
1st 0.1498185 150.4809 0.2439951 0.27265613
2nd 0.1876176 188.4472 0.0000000 0.03791987
3rd 0.1888766 189.7117 0.2446010 0.27323905
All 0.5665090 569.0139 0.2444172 0.27306228
> e7 <- earth(pclass ~ ., data=etitanic, degree=2, wp=c(1,.001,.001))
> printh(e7)
===e7 
Selected 8 of 17 terms, and 4 of 5 predictors
Termination condition: Reached nk 21
Importance: age, parch, survived, sibsp, sexmale-unused
Number of terms at each degree of interaction: 1 3 4

          GCV      RSS        GRSq        RSq
1st 0.1446768 146.0263  0.26994041 0.29418743
2nd 0.1903255 192.1007 -0.01442347 0.01926795
3rd 0.1977757 199.6204  0.20900943 0.23528011
All 0.4343262 438.3772  0.26959508 0.29385356
> printh(summary(e7))
===summary(e7) 
Call: earth(formula=pclass~., data=etitanic, wp=c(1,0.001,0.001), degree=2)

                                1st          2nd         3rd
(Intercept)              0.11122944  0.208223042  0.68054751
survived                 0.36895988 -0.129640255 -0.23931962
h(age-44)                0.03812399 -0.007721391 -0.03040260
h(2-parch)               0.17926095  0.072120537 -0.25138149
survived * h(52-age)    -0.00527271  0.006970050 -0.00169734
h(48-age) * h(2-parch)  -0.00631659 -0.002155682  0.00847228
h(age-48) * h(2-parch)  -0.02034190  0.002942071  0.01739983
h(1-sibsp) * h(1-parch) -0.13130286 -0.036388271  0.16769113

Selected 8 of 17 terms, and 4 of 5 predictors
Termination condition: Reached nk 21
Importance: age, parch, survived, sibsp, sexmale-unused
Number of terms at each degree of interaction: 1 3 4

          GCV      RSS        GRSq        RSq
1st 0.1446768 146.0263  0.26994041 0.29418743
2nd 0.1903255 192.1007 -0.01442347 0.01926795
3rd 0.1977757 199.6204  0.20900943 0.23528011
All 0.4343262 438.3772  0.26959508 0.29385356
> if (PLOT)
+     plot(e7, pt.col=as.numeric(etitanic$pclass)+1, nresponse=1)
> 
> cat("--- earth_regress ---------------------------------\n")
--- earth_regress ---------------------------------
> 
> msg = "earth_regress with trees data, single response, no weights"
> cat("Test:", msg, "\n")
Test: earth_regress with trees data, single response, no weights 
> 
> data(trees)
> y <- trees$Volume
> x <- cbind(trees$Girth, trees$Height)
> colnames(x) <- c("girth", "height")
> 
> a.lm <- lm(y ~ x)
> a.lm.rss <- sum((a.lm$fitted.values - y)^2)
> if (is.null(dim(a.lm$coefficients)))
+     dim(a.lm$coefficients) <- c(length(a.lm$coefficients), 1)
> a <- earth:::earth_regress(x, y)
> rownames(a.lm$coefficients) <- rownames(a$coefficients)
> check.almost.equal(a.lm$coefficients, a$coefficients, msg=paste("coefficients [", msg, "]", sep=""))
> check.almost.equal(a.lm.rss, a$rss, msg=paste("rss [", msg, "]"))
> check.almost.equal(a.lm$residuals, a$residuals, msg=paste("residuals [", msg, "]"))
> 
> msg = "earth_regress with ozone1 data, multiple responses, no weights"
> cat("Test:", msg, "\n")
Test: earth_regress with ozone1 data, multiple responses, no weights 
> 
> data(ozone1)
> y <- cbind(ozone1$O3, ozone1$O3 ^ 2)
> colnames(y) <- c("O3", "O32")
> x <- cbind(ozone1$wind, ozone1$humidity, ozone1$temp)
> colnames(x) <- c("wind", "humidity", "temp")
> 
> a.lm <- lm(y ~ x)
> a.lm.rss <- sum((a.lm$fitted.values - y)^2)
> a <- earth:::earth_regress(x, y)
> rownames(a.lm$coefficients) <- rownames(a$coefficients)
> check.almost.equal(a.lm$coefficients, a$coefficients, msg=paste("coefficients [", msg, "]"))
> check.almost.equal(a.lm.rss, a$rss, msg=paste("rss [", msg, "]", sep=""))
> check.almost.equal(a.lm$residuals, a$residuals, msg=paste("residuals [", msg, "]", sep=""))
> 
> # msg = "earth_regress with ozone1 data, multiple responses with case weights"
> # cat("Test:", msg, "\n")
> #
> # # options(digits=10)
> # weights. <- rep(.5, nrow(x))
> # weights.[1] <- 1
> # weights.[2] <- 2
> # weights.[3] <- 3
> # weights.[4] <- 4
> # weights.[5] <- 5
> # a.lm <- lm(y ~ x, weights=weights.)
> # # a.lm.rss <- sum((a.lm$fitted.values - y)^2) # line below is equivalent
> # a.lm.rss <- sum(a.lm$residuals^2)
> # a <- earth:::earth_regress(x, y, weights=weights.)
> # rownames(a.lm$coefficients) <- rownames(a$coefficients)
> # check.almost.equal(a.lm$coefficients, a$coefficients, msg=paste("coefficients [", msg, "]", sep=""))
> # check.almost.equal(a.lm.rss, a$rss, msg=paste("rss [", msg, "]", sep=""))
> # check.almost.equal(a.lm$residuals, a$residuals, msg=paste("residuals [", msg, "]", sep=""))
> 
> # msg = "earth_regress case weights with zero weights 1"
> # cat("Test:", msg, "\n")
> #
> # weights. <- rep(1, nrow(x))
> # weights.[2] <- 0
> # weights.[4] <- 0
> # a.lm <- lm(y ~ x, weights=weights.)
> # # a.lm.rss <- sum((a.lm$fitted.values - y)^2) # line below is equivalent
> # a.lm.rss <- sum(a.lm$residuals^2)
> # a <- earth:::earth_regress(x, y, weights=weights.)
> # rownames(a.lm$coefficients) <- rownames(a$coefficients)
> # # options(digits=10)
> # check.almost.equal(a.lm$coefficients, a$coefficients, msg=paste("coefficients [", msg, "]", sep=""))
> # check.almost.equal(a.lm.rss, a$rss, msg=paste("rss [", msg, "]", sep=""))
> # check.almost.equal(a.lm$residuals, a$residuals, max=1e-6, msg=paste("residuals [", msg, "]", sep=""))
> #
> # msg = "earth_regress case weights with zero weights 2"
> # cat("Test:", msg, "\n")
> # weights. <- rep(1, nrow(x))
> # weights.[5] <- 0
> # weights.[6] <- 0
> # weights.[7] <- 0
> # weights.[21] <- 0
> # weights.[22] <- 0
> # weights.[23] <- 0
> # weights.[24] <- 0
> # weights.[25] <- 0
> # weights.[26] <- 0
> # weights.[27] <- 0
> # a.lm <- lm(y ~ x, weights=weights.)
> # # a.lm.rss <- sum((a.lm$fitted.values - y)^2) # line below is equivalent
> # a.lm.rss <- sum(a.lm$residuals^2)
> # a <- earth:::earth_regress(x, y, weights=weights.)
> # rownames(a.lm$coefficients) <- rownames(a$coefficients)
> # check.almost.equal(a.lm$coefficients, a$coefficients, msg=paste("coefficients [", msg, "]", sep=""))
> # check.almost.equal(a.lm.rss, a$rss, msg=paste("rss [", msg, "]", sep=""))
> # check.almost.equal(a.lm$residuals, a$residuals, max=1e-6, msg=paste("residuals [", msg, "]", sep=""))
> #
> # msg = "earth_regress case weights with zero weights and missing columns 1"
> # cat("Test:", msg, "\n")
> # x <- cbind(ozone1$wind, ozone1$humidity, ozone1$temp, ozone1$wind^2, ozone1$humidity^2, ozone1$temp^2)
> # weights. <- rep(1, nrow(x))
> # weights.[5] <- 0
> # weights.[6] <- 0
> # weights.[7] <- 0
> # weights.[21] <- 0
> # weights.[22] <- 0
> # weights.[23] <- 0
> # weights.[24] <- 0
> # weights.[25] <- 0
> # weights.[26] <- 0
> # weights.[27] <- 0
> # colnames(x) <- c("wind", "humidity", "temp", "wind2", "humidity2", "temp2")
> # used.cols = as.logical(c(1,0,1,0,1,1))
> # x.missing <- x[,used.cols]
> # a.lm <- lm(y ~ x.missing, weights=weights.)
> # a.lm.rss <- sum((a.lm$fitted.values - y)^2) # line below is equivalent
> # a.lm.rss <- sum(a.lm$residuals^2)
> # a <- earth:::earth_regress(x, y, weights=weights., used.cols=used.cols)
> # rownames(a.lm$coefficients) <- rownames(a$coefficients)
> # check.almost.equal(a.lm$coefficients, a$coefficients, msg=paste("coefficients [", msg, "]", sep=""))
> # check.almost.equal(a.lm.rss, a$rss, msg=paste("rss [", msg, "]", sep=""))
> # check.almost.equal(a.lm$residuals, a$residuals, max=1e-6, msg=paste("residuals [", msg, "]", sep=""))
> #
> # msg = "earth_regress case weights with zero weights and missing columns 2"
> # cat("Test:", msg, "\n")
> # x <- cbind(ozone1$wind, ozone1$humidity, ozone1$temp, ozone1$wind^2, ozone1$humidity^2, ozone1$temp^2)
> # weights. <- rep(1, nrow(x))
> # weights.[5] <- .1
> # weights.[6] <- .2
> # weights.[7] <- 1.9
> # weights.[21] <- .59
> # colnames(x) <- c("wind", "humidity", "temp", "wind2", "humidity2", "temp2")
> # used.cols = as.logical(c(0,1,0,0,1,0))
> # x.missing <- x[,used.cols]
> # a.lm <- lm(y ~ x.missing, weights=weights.)
> # a.lm.rss <- sum((a.lm$fitted.values - y)^2) # line below is equivalent
> # a.lm.rss <- sum(a.lm$residuals^2)
> # a <- earth:::earth_regress(x, y, weights=weights., used.cols=used.cols)
> # rownames(a.lm$coefficients) <- rownames(a$coefficients)
> # check.almost.equal(a.lm$coefficients, a$coefficients, msg=paste("coefficients [", msg, "]", sep=""))
> # check.almost.equal(a.lm.rss, a$rss, msg=paste("rss [", msg, "]", sep=""))
> # check.almost.equal(a.lm$residuals, a$residuals, max=1e-6, msg=paste("residuals [", msg, "]", sep=""))
> 
> cat("---standard method functions ------------------------\n")
---standard method functions ------------------------
> 
> short.etitanic <- etitanic[seq(from=1, to=1000, by=20),]
> a1 <- earth(pclass ~ ., data=short.etitanic, glm=list(family=binomial), trace=0)
> printh(variable.names(a1))
===variable.names(a1) 
[1] "survived" "sexmale"  "age"      "sibsp"    "parch"   
> printh(case.names(a1))
===case.names(a1) 
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15"
[16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
[31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45"
[46] "46" "47" "48" "49" "50"
> printh(case.names(a1, use.names=FALSE))
===case.names(a1, use.names = FALSE) 
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15"
[16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
[31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45"
[46] "46" "47" "48" "49" "50"
> 
> named.short.etitanic <- short.etitanic
> rownames(named.short.etitanic) <- paste("xx", 1:nrow(named.short.etitanic))
> a2 <- earth(pclass ~ ., data=named.short.etitanic, glm=list(family=binomial), trace=0)
> printh(variable.names(a2))
===variable.names(a2) 
[1] "survived" "sexmale"  "age"      "sibsp"    "parch"   
> printh(case.names(a2))
===case.names(a2) 
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15"
[16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
[31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45"
[46] "46" "47" "48" "49" "50"
> printh(case.names(a2, use.names=FALSE))
===case.names(a2, use.names = FALSE) 
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15"
[16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
[31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45"
[46] "46" "47" "48" "49" "50"
> 
> printh(deviance(a1), expect.warning=TRUE)
===deviance(a1)  expect warning -->Warning: deviance.earth: returning earth (not GLM) deviance
[1] 25.48701
> printh(deviance(a1, warn=FALSE))
===deviance(a1, warn = FALSE) [1] 25.48701
> printh(effects(a1), expect.warning=TRUE)
===effects(a1)  expect warning -->Warning: effects.earth: returning NULL
NULL
> printh(effects(a1, warn=FALSE))
===effects(a1, warn = FALSE) NULL
> printh(family(a1))
===family(a1) 

Family: binomial 
Link function: logit 

> printh(anova(a1), expect.warning=TRUE)
===anova(a1)  expect warning -->Warning: anova.earth: returning NULL
NULL
> printh(anova(a1, warn=FALSE))
===anova(a1, warn = FALSE) NULL
> printh(family(a1))
===family(a1) 

Family: binomial 
Link function: logit 

> 
> # TODO removed because causes different results on different machines
> # cat("--- thresh=0 -----------------------------------------\n")
> #
> # a.no.thresh <- earth(O3 ~ ., data = ozone1, thresh=0, nk=1000, degree=2, trace=4)
> # printh(a.no.thresh)
> # printh(summary(a.no.thresh))
> # plotmo(a.no.thresh, degree1=1, degree2=c(4,9,16), clip=0, , caption="test with thresh=0", trace=-1)
> 
> # test the way plotmo gets the data with earth with a formula interface
> # use strange data name se to make sure eval gets correct environment (don't pick up se in plotmo)
> se <- ozone1
> a <- earth(O3 ~ ., data=se, degree=2, keepxy=0)
> printh(summary(a))
===summary(a) 
Call: earth(formula=O3~., data=se, keepxy=0, degree=2)

                            coefficients
(Intercept)                   13.2169900
h(temp-58)                     0.3726072
h(194-ibt)                    -0.0455100
h(200-vis)                     0.0222462
h(96-doy)                     -0.1223029
h(doy-96)                     -0.0240235
h(5730-vh) * h(temp-58)       -0.0104496
h(wind-7) * h(200-vis)        -0.0180898
h(55-humidity) * h(temp-58)   -0.0222754
h(temp-58) * h(dpg-52)        -0.0168249
h(temp-58) * h(52-dpg)         0.0041232
h(1105-ibh) * h(21-dpg)       -0.0001022

Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
> plotmo(a, trace=2, caption="getdata earth test1")
plotmo trace 2: plotmo(object=a, caption="getdata earth test1", trace=2)
--get.model.env for object with class earth
object call is earth(formula=O3~., data=se, keepxy=0, degree=2)
using the environment saved in $terms of the earth model: R_GlobalEnv
--plotmo_prolog for earth object 'a'
--plotmo_x for earth object

get.object.x:
object$x is NULL (and it has no colnames)

object call is earth(formula=O3~., data=se, keepxy=0, degree=2)

get.x.from.model.frame:
formula(object) is O3 ~ vh + wind + humidity + temp + ibh + dpg + ibt + vis ...
naked formula is the same
formula is valid, now looking for data for the model.frame
object$model is NULL (and it has no colnames)
object$data is NULL (and it has no colnames)
argument 2 of the call is 'data'
eval(call$data, R_GlobalEnv)
call$data is usable and has column names O3 vh wind humidity temp ibh dpg ibt vis doy
na.action(object) is "na.fail"
stats::model.frame(O3 ~ vh + wind + humidity + temp + ib..., data=call$data, na.action="na.fail")
x=model.frame[,-1] is usable and has column names vh wind humidity temp ibh dpg ibt vis doy
plotmo_x returned[330,9]:
      vh wind humidity temp  ibh dpg ibt vis doy
1   5710    4       28   40 2693 -25  87 250  33
2   5700    3       37   45  590 -24 128 100  34
3   5760    3       51   54 1450  25 139  60  35
... 5720    4       69   35 1568  15 121  60  36
330 5550    4       85   39 5000   8  44 100 390

----Metadata: plotmo_predict with nresponse=NULL and newdata=NULL
calling predict.earth with NULL newdata
stats::predict(earth.object, NULL, type="response")
predict returned[330,1]:
           O3
1   0.6423433
2   2.4875500
3   6.3679385
... 5.6710623
330 1.5521976
predict after processing with nresponse=NULL is [330,1]:
           O3
1   0.6423433
2   2.4875500
3   6.3679385
... 5.6710623
330 1.5521976

----Metadata: plotmo_fitted with nresponse=NULL
stats::fitted(object=earth.object)
fitted(object) returned[330,1]:
           O3
1   0.6423433
2   2.4875500
3   6.3679385
... 5.6710623
330 1.5521976
fitted(object) after processing with nresponse=NULL is [330,1]:
           O3
1   0.6423433
2   2.4875500
3   6.3679385
... 5.6710623
330 1.5521976

----Metadata: plotmo_y with nresponse=NULL
--plotmo_y with nresponse=NULL for earth object

get.object.y:
object$y is NULL (and it has no colnames)

object call is earth(formula=O3~., data=se, keepxy=0, degree=2)

get.y.from.model.frame:
formula(object) is O3 ~ vh + wind + humidity + temp + ibh + dpg + ibt + vis ...
formula is valid, now looking for data for the model.frame
object$model is NULL (and it has no colnames)
object$data is NULL (and it has no colnames)
argument 2 of the call is 'data'
eval(call$data, R_GlobalEnv)
call$data is usable and has column names O3 vh wind humidity temp ibh dpg ibt vis doy
na.action(object) is "na.fail"
stats::model.frame(O3 ~ vh + wind + humidity + temp + ib..., data=call$data, na.action="na.fail")
y=model.frame[,1] is usable and has column name O3
plotmo_y returned[330,1]:
    O3
1    3
2    5
3    5
...  6
330  1
plotmo_y after processing with nresponse=NULL is [330,1]:
    O3
1    3
2    5
3    5
...  6
330  1
converted nresponse=NA to nresponse=1
nresponse=1 (was NA) ncol(fitted) 1 ncol(predict) 1 ncol(y) 1

----Metadata: plotmo_y with nresponse=1
--plotmo_y with nresponse=1 for earth object

get.object.y:
object$y is NULL (and it has no colnames)

object call is earth(formula=O3~., data=se, keepxy=0, degree=2)

get.y.from.model.frame:
formula(object) is O3 ~ vh + wind + humidity + temp + ibh + dpg + ibt + vis ...
formula is valid, now looking for data for the model.frame
object$model is NULL (and it has no colnames)
object$data is NULL (and it has no colnames)
argument 2 of the call is 'data'
eval(call$data, R_GlobalEnv)
call$data is usable and has column names O3 vh wind humidity temp ibh dpg ibt vis doy
na.action(object) is "na.fail"
stats::model.frame(O3 ~ vh + wind + humidity + temp + ib..., data=call$data, na.action="na.fail")
y=model.frame[,1] is usable and has column name O3
got model response from model.frame(O3 ~ vh + wind + humidity + temp + ib...,
                                    data=call$data, na.action="na.fail")
plotmo_y returned[330,1]:
    O3
1    3
2    5
3    5
...  6
330  1
plotmo_y after processing with nresponse=1 is [330,1]:
    O3
1    3
2    5
3    5
...  6
330  1
got response name "O3" from yhat
resp.levs is NULL

----Metadata: done

number of x values: vh 53 wind 11 humidity 65 temp 63 ibh 196 dpg 128 ibt 193...

----plotmo_singles for earth object
singles: 4 temp, 7 ibt, 8 vis, 9 doy 

----plotmo_pairs for earth object
pairs:
     [,1]         [,2]    
[1,] "1 vh"       "4 temp"
[2,] "2 wind"     "8 vis" 
[3,] "3 humidity" "4 temp"
[4,] "4 temp"     "6 dpg" 
[5,] "5 ibh"      "6 dpg" 

graphics::par(mfrow=c(3,3), mgp=c(1.5,0.4,0), tcl=-0.3, font.main=2,
              mar=c(3,2,1.2,0.8), oma=c(0,0,4,0), cex.main=1.2, cex.lab=1,
              cex.axis=1, cex=0.66)

----Figuring out ylim
--get.ylim.by.dummy.plots
--plot.degree1(draw.plot=FALSE)
degree1 plot1 (pmethod "plotmo") variable temp
newdata[50,9]:
      vh wind humidity     temp    ibh dpg   ibt vis   doy
1   5760    5       64 25.00000 2112.5  24 167.5 120 205.5
2   5760    5       64 26.38776 2112.5  24 167.5 120 205.5
3   5760    5       64 27.77551 2112.5  24 167.5 120 205.5
... 5760    5       64 29.16327 2112.5  24 167.5 120 205.5
50  5760    5       64 93.00000 2112.5  24 167.5 120 205.5
stats::predict(earth.object, data.frame[50,9], type="response")
predict returned[50,1]:
          O3
1   11.16010
2   11.16010
3   11.16010
... 11.16010
50  28.24212
predict after processing with nresponse=1 is [50,1]:
          O3
1   11.16010
2   11.16010
3   11.16010
... 11.16010
50  28.24212
Reducing trace level for subsequent degree1 plots
degree1 plot2 (pmethod "plotmo") variable ibt
degree1 plot3 (pmethod "plotmo") variable vis
degree1 plot4 (pmethod "plotmo") variable doy
--plot.degree2(draw.plot=FALSE)
degree2 plot1 (pmethod "plotmo") variables vh:temp
newdata[400,9]:
          vh wind humidity temp    ibh dpg   ibt vis   doy
1   5320.000    5       64   25 2112.5  24 167.5 120 205.5
2   5353.158    5       64   25 2112.5  24 167.5 120 205.5
3   5386.316    5       64   25 2112.5  24 167.5 120 205.5
... 5419.474    5       64   25 2112.5  24 167.5 120 205.5
400 5950.000    5       64   93 2112.5  24 167.5 120 205.5
stats::predict(earth.object, data.frame[400,9], type="response")
predict returned[400,1]:
          O3
1   11.16010
2   11.16010
3   11.16010
... 11.16010
400 28.24212
predict after processing with nresponse=1 is [400,1]:
          O3
1   11.16010
2   11.16010
3   11.16010
... 11.16010
400 28.24212
Reducing trace level for subsequent degree2 plots
degree2 plot2 (pmethod "plotmo") variables wind:vis
degree2 plot3 (pmethod "plotmo") variables humidity:temp
degree2 plot4 (pmethod "plotmo") variables temp:dpg
degree2 plot5 (pmethod "plotmo") variables ibh:dpg
--done get.ylim.by.dummy.plots

ylim c(-15.89, 38.55)    clip TRUE

--plot.degree1(draw.plot=TRUE)

 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5

graphics::plot.default(x=c(25,26.39,27.7...), y=c(11.16,11.16,1...), type="n",
                       main="1 temp", xlab="", ylab="", xaxt="s", yaxt="s",
                       xlim=c(25,93), ylim=c(-15.89,38.55))
--plot.degree2(draw.plot=TRUE)
persp(vh:temp) theta -35
persp(wind:vis) theta 145
persp(humidity:temp) theta -35
persp(temp:dpg) theta 235
persp(ibh:dpg) theta 235
> a <- earth(O3 ~ ., data=se, degree=2, keepxy=1)
> printh(summary(a))
===summary(a) 
Call: earth(formula=O3~., data=se, keepxy=1, degree=2)

                            coefficients
(Intercept)                   13.2169900
h(temp-58)                     0.3726072
h(194-ibt)                    -0.0455100
h(200-vis)                     0.0222462
h(96-doy)                     -0.1223029
h(doy-96)                     -0.0240235
h(5730-vh) * h(temp-58)       -0.0104496
h(wind-7) * h(200-vis)        -0.0180898
h(55-humidity) * h(temp-58)   -0.0222754
h(temp-58) * h(dpg-52)        -0.0168249
h(temp-58) * h(52-dpg)         0.0041232
h(1105-ibh) * h(21-dpg)       -0.0001022

Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
> plotmo(a, trace=1, caption="getdata earth test2")
stats::predict(earth.object, NULL, type="response")
stats::fitted(object=earth.object)
got model response from object$y

 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5

> a <- earth(O3 ~ ., data=se, degree=2, keepxy=1)
> se <- NULL
> printh(summary(a))
===summary(a) 
Call: earth(formula=O3~., data=se, keepxy=1, degree=2)

                            coefficients
(Intercept)                   13.2169900
h(temp-58)                     0.3726072
h(194-ibt)                    -0.0455100
h(200-vis)                     0.0222462
h(96-doy)                     -0.1223029
h(doy-96)                     -0.0240235
h(5730-vh) * h(temp-58)       -0.0104496
h(wind-7) * h(200-vis)        -0.0180898
h(55-humidity) * h(temp-58)   -0.0222754
h(temp-58) * h(dpg-52)        -0.0168249
h(temp-58) * h(52-dpg)         0.0041232
h(1105-ibh) * h(21-dpg)       -0.0001022

Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
> plotmo(a, trace=2, caption="getdata earth test3")
plotmo trace 2: plotmo(object=a, caption="getdata earth test3", trace=2)
--get.model.env for object with class earth
object call is earth(formula=O3~., data=se, keepxy=1, degree=2)
using the environment saved in $terms of the earth model: R_GlobalEnv
--plotmo_prolog for earth object 'a'
--plotmo_x for earth object

get.object.x:
object$x is NULL (and it has no colnames)

object call is earth(formula=O3~., data=se, keepxy=1, degree=2)

get.x.from.model.frame:
formula(object) is O3 ~ vh + wind + humidity + temp + ibh + dpg + ibt + vis ...
naked formula is the same
formula is valid, now looking for data for the model.frame
object$model is NULL (and it has no colnames)
object$data is usable and has column names O3 vh wind humidity temp ibh dpg ibt vis doy
na.action(object) is "na.fail"
stats::model.frame(O3 ~ vh + wind + humidity + temp + ib..., data=object$data, na.action="na.fail")
x=model.frame[,-1] is usable and has column names vh wind humidity temp ibh dpg ibt vis doy
plotmo_x returned[330,9]:
      vh wind humidity temp  ibh dpg ibt vis doy
1   5710    4       28   40 2693 -25  87 250  33
2   5700    3       37   45  590 -24 128 100  34
3   5760    3       51   54 1450  25 139  60  35
... 5720    4       69   35 1568  15 121  60  36
330 5550    4       85   39 5000   8  44 100 390

----Metadata: plotmo_predict with nresponse=NULL and newdata=NULL
calling predict.earth with NULL newdata
stats::predict(earth.object, NULL, type="response")
predict returned[330,1]:
           O3
1   0.6423433
2   2.4875500
3   6.3679385
... 5.6710623
330 1.5521976
predict after processing with nresponse=NULL is [330,1]:
           O3
1   0.6423433
2   2.4875500
3   6.3679385
... 5.6710623
330 1.5521976

----Metadata: plotmo_fitted with nresponse=NULL
stats::fitted(object=earth.object)
fitted(object) returned[330,1]:
           O3
1   0.6423433
2   2.4875500
3   6.3679385
... 5.6710623
330 1.5521976
fitted(object) after processing with nresponse=NULL is [330,1]:
           O3
1   0.6423433
2   2.4875500
3   6.3679385
... 5.6710623
330 1.5521976

----Metadata: plotmo_y with nresponse=NULL
--plotmo_y with nresponse=NULL for earth object

get.object.y:
object$y is usable and has column name O3
plotmo_y returned[330,1]:
    O3
1    3
2    5
3    5
...  6
330  1
plotmo_y after processing with nresponse=NULL is [330,1]:
    O3
1    3
2    5
3    5
...  6
330  1
converted nresponse=NA to nresponse=1
nresponse=1 (was NA) ncol(fitted) 1 ncol(predict) 1 ncol(y) 1

----Metadata: plotmo_y with nresponse=1
--plotmo_y with nresponse=1 for earth object

get.object.y:
object$y is usable and has column name O3
got model response from object$y
plotmo_y returned[330,1]:
    O3
1    3
2    5
3    5
...  6
330  1
plotmo_y after processing with nresponse=1 is [330,1]:
    O3
1    3
2    5
3    5
...  6
330  1
got response name "O3" from yhat
resp.levs is NULL

----Metadata: done

number of x values: vh 53 wind 11 humidity 65 temp 63 ibh 196 dpg 128 ibt 193...

----plotmo_singles for earth object
singles: 4 temp, 7 ibt, 8 vis, 9 doy 

----plotmo_pairs for earth object
pairs:
     [,1]         [,2]    
[1,] "1 vh"       "4 temp"
[2,] "2 wind"     "8 vis" 
[3,] "3 humidity" "4 temp"
[4,] "4 temp"     "6 dpg" 
[5,] "5 ibh"      "6 dpg" 

graphics::par(mfrow=c(3,3), mgp=c(1.5,0.4,0), tcl=-0.3, font.main=2,
              mar=c(3,2,1.2,0.8), oma=c(0,0,4,0), cex.main=1.2, cex.lab=1,
              cex.axis=1, cex=0.66)

----Figuring out ylim
--get.ylim.by.dummy.plots
--plot.degree1(draw.plot=FALSE)
degree1 plot1 (pmethod "plotmo") variable temp
newdata[50,9]:
      vh wind humidity     temp    ibh dpg   ibt vis   doy
1   5760    5       64 25.00000 2112.5  24 167.5 120 205.5
2   5760    5       64 26.38776 2112.5  24 167.5 120 205.5
3   5760    5       64 27.77551 2112.5  24 167.5 120 205.5
... 5760    5       64 29.16327 2112.5  24 167.5 120 205.5
50  5760    5       64 93.00000 2112.5  24 167.5 120 205.5
stats::predict(earth.object, data.frame[50,9], type="response")
predict returned[50,1]:
          O3
1   11.16010
2   11.16010
3   11.16010
... 11.16010
50  28.24212
predict after processing with nresponse=1 is [50,1]:
          O3
1   11.16010
2   11.16010
3   11.16010
... 11.16010
50  28.24212
Reducing trace level for subsequent degree1 plots
degree1 plot2 (pmethod "plotmo") variable ibt
degree1 plot3 (pmethod "plotmo") variable vis
degree1 plot4 (pmethod "plotmo") variable doy
--plot.degree2(draw.plot=FALSE)
degree2 plot1 (pmethod "plotmo") variables vh:temp
newdata[400,9]:
          vh wind humidity temp    ibh dpg   ibt vis   doy
1   5320.000    5       64   25 2112.5  24 167.5 120 205.5
2   5353.158    5       64   25 2112.5  24 167.5 120 205.5
3   5386.316    5       64   25 2112.5  24 167.5 120 205.5
... 5419.474    5       64   25 2112.5  24 167.5 120 205.5
400 5950.000    5       64   93 2112.5  24 167.5 120 205.5
stats::predict(earth.object, data.frame[400,9], type="response")
predict returned[400,1]:
          O3
1   11.16010
2   11.16010
3   11.16010
... 11.16010
400 28.24212
predict after processing with nresponse=1 is [400,1]:
          O3
1   11.16010
2   11.16010
3   11.16010
... 11.16010
400 28.24212
Reducing trace level for subsequent degree2 plots
degree2 plot2 (pmethod "plotmo") variables wind:vis
degree2 plot3 (pmethod "plotmo") variables humidity:temp
degree2 plot4 (pmethod "plotmo") variables temp:dpg
degree2 plot5 (pmethod "plotmo") variables ibh:dpg
--done get.ylim.by.dummy.plots

ylim c(-15.89, 38.55)    clip TRUE

--plot.degree1(draw.plot=TRUE)

 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5

graphics::plot.default(x=c(25,26.39,27.7...), y=c(11.16,11.16,1...), type="n",
                       main="1 temp", xlab="", ylab="", xaxt="s", yaxt="s",
                       xlim=c(25,93), ylim=c(-15.89,38.55))
--plot.degree2(draw.plot=TRUE)
persp(vh:temp) theta -35
persp(wind:vis) theta 145
persp(humidity:temp) theta -35
persp(temp:dpg) theta 235
persp(ibh:dpg) theta 235
> se <- ozone1
> a <- earth(O3 ~ ., data=se, degree=2, keepxy=0)
> se <- NULL
> printh(summary(a))
===summary(a) 
Call: earth(formula=O3~., data=se, keepxy=0, degree=2)

                            coefficients
(Intercept)                   13.2169900
h(temp-58)                     0.3726072
h(194-ibt)                    -0.0455100
h(200-vis)                     0.0222462
h(96-doy)                     -0.1223029
h(doy-96)                     -0.0240235
h(5730-vh) * h(temp-58)       -0.0104496
h(wind-7) * h(200-vis)        -0.0180898
h(55-humidity) * h(temp-58)   -0.0222754
h(temp-58) * h(dpg-52)        -0.0168249
h(temp-58) * h(52-dpg)         0.0041232
h(1105-ibh) * h(21-dpg)       -0.0001022

Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
> expect.err(try(plotmo(a, trace=0, caption="getdata earth test4")), "cannot get the original model predictors")

Looked unsuccessfully for the original predictors in the following places:

(1) object$x: NULL

(2) model.frame: object 'O3' not found

(3) getCall(object)$x: NULL

Error : cannot get the original model predictors
Got expected error from try(plotmo(a, trace = 0, caption = "getdata earth test4"))
> 
> # test the way plotmo gets the data with earth with the default interface
> se <- ozone1
> a <- earth(se[,2:10], se[,1], degree=2, keepxy=0)
> printh(summary(a))
===summary(a) 
Call: earth(x=se[,2:10], y=se[,1], keepxy=0, degree=2)

                            coefficients
(Intercept)                   13.2169900
h(temp-58)                     0.3726072
h(194-ibt)                    -0.0455100
h(200-vis)                     0.0222462
h(96-doy)                     -0.1223029
h(doy-96)                     -0.0240235
h(5730-vh) * h(temp-58)       -0.0104496
h(wind-7) * h(200-vis)        -0.0180898
h(55-humidity) * h(temp-58)   -0.0222754
h(temp-58) * h(dpg-52)        -0.0168249
h(temp-58) * h(52-dpg)         0.0041232
h(1105-ibh) * h(21-dpg)       -0.0001022

Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
> plotmo(a, trace=0, caption="getdata earth test5")
 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5
> a <- earth(se[,2:10], se[,1], degree=2, keepxy=1)
> printh(summary(a))
===summary(a) 
Call: earth(x=se[,2:10], y=se[,1], keepxy=1, degree=2)

                            coefficients
(Intercept)                   13.2169900
h(temp-58)                     0.3726072
h(194-ibt)                    -0.0455100
h(200-vis)                     0.0222462
h(96-doy)                     -0.1223029
h(doy-96)                     -0.0240235
h(5730-vh) * h(temp-58)       -0.0104496
h(wind-7) * h(200-vis)        -0.0180898
h(55-humidity) * h(temp-58)   -0.0222754
h(temp-58) * h(dpg-52)        -0.0168249
h(temp-58) * h(52-dpg)         0.0041232
h(1105-ibh) * h(21-dpg)       -0.0001022

Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
> plotmo(a, trace=0, caption="getdata earth test6")
 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5
> a <- earth(se[,2:10], se[,1], degree=2, keepxy=1)
> se <- NULL
> printh(summary(a))
===summary(a) 
Call: earth(x=se[,2:10], y=se[,1], keepxy=1, degree=2)

                            coefficients
(Intercept)                   13.2169900
h(temp-58)                     0.3726072
h(194-ibt)                    -0.0455100
h(200-vis)                     0.0222462
h(96-doy)                     -0.1223029
h(doy-96)                     -0.0240235
h(5730-vh) * h(temp-58)       -0.0104496
h(wind-7) * h(200-vis)        -0.0180898
h(55-humidity) * h(temp-58)   -0.0222754
h(temp-58) * h(dpg-52)        -0.0168249
h(temp-58) * h(52-dpg)         0.0041232
h(1105-ibh) * h(21-dpg)       -0.0001022

Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
> plotmo(a, trace=0, caption="getdata earth test7")
 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5
> se <- ozone1
> a <- earth(se[,2:10], se[,1], degree=2, keepxy=0)
> se <- NULL
> expect.err(try(plotmo(a, trace=0, caption="getdata earth test8")), "cannot get the original model predictors")

Looked unsuccessfully for the original predictors in the following places:

(1) object$x: NULL

(2) model.frame: no formula in getCall(object)

(3) getCall(object)$x: NULL

Error : cannot get the original model predictors
Got expected error from try(plotmo(a, trace = 0, caption = "getdata earth test8"))
> se <- ozone1
> a <- earth(se[,2:10], se[,1], degree=2, keepxy=0)
> # TODO error message could be improved here
> se$vh <- NULL # vh is unused (but plotmo still needs it --- why?)
> expect.err(try(plotmo(a, trace=0, caption="getdata earth test9")), "cannot get the original model predictors") # plotmo.x.default cannot get the x matrix

Looked unsuccessfully for the original predictors in the following places:

(1) object$x: NULL

(2) model.frame: no formula in getCall(object)

(3) getCall(object)$x: undefined columns selected

Error : cannot get the original model predictors
Got expected error from try(plotmo(a, trace = 0, caption = "getdata earth test9"))
> se <- ozone1
> a <- earth(se[,2:10], se[,1], degree=2, keepxy=TRUE)
> se$vh <- NULL # vh is unused (but plotmo still needs it --- why?)
> printh(summary(a))
===summary(a) 
Call: earth(x=se[,2:10], y=se[,1], keepxy=TRUE, degree=2)

                            coefficients
(Intercept)                   13.2169900
h(temp-58)                     0.3726072
h(194-ibt)                    -0.0455100
h(200-vis)                     0.0222462
h(96-doy)                     -0.1223029
h(doy-96)                     -0.0240235
h(5730-vh) * h(temp-58)       -0.0104496
h(wind-7) * h(200-vis)        -0.0180898
h(55-humidity) * h(temp-58)   -0.0222754
h(temp-58) * h(dpg-52)        -0.0168249
h(temp-58) * h(52-dpg)         0.0041232
h(1105-ibh) * h(21-dpg)       -0.0001022

Selected 12 of 21 terms, and 9 of 9 predictors
Termination condition: Reached nk 21
Importance: temp, humidity, ibt, doy, ibh, dpg, vis, wind, vh
Number of terms at each degree of interaction: 1 5 6
GCV 13.40805    RSS 3693.401    GRSq 0.7917216    RSq 0.825085
> plotmo(a, trace=0, caption="getdata earth test9")
 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5
> 
> # test the way plotmo gets the data with lm
> se <- ozone1
> a <- lm(O3 ~ ., data=se)
> printh(summary(a))
===summary(a) 

Call:
lm(formula = O3 ~ ., data = se)

Residuals:
     Min       1Q   Median       3Q      Max 
-12.1011  -2.9289  -0.2715   2.7080  13.3687 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 20.3135755 29.5193067   0.688  0.49186    
vh          -0.0054271  0.0053985  -1.005  0.31551    
wind        -0.0545832  0.1348425  -0.405  0.68590    
humidity     0.0809741  0.0188394   4.298 2.29e-05 ***
temp         0.2755492  0.0497912   5.534 6.52e-08 ***
ibh         -0.0002338  0.0002956  -0.791  0.42944    
dpg         -0.0033629  0.0112805  -0.298  0.76581    
ibt          0.0296411  0.0136088   2.178  0.03013 *  
vis         -0.0079910  0.0037503  -2.131  0.03387 *  
doy         -0.0091194  0.0027745  -3.287  0.00113 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 4.441 on 320 degrees of freedom
Multiple R-squared:  0.7012,	Adjusted R-squared:  0.6927 
F-statistic: 83.42 on 9 and 320 DF,  p-value: < 2.2e-16

> plotmo(a, trace=0, caption="getdata lm test1")
 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5
> a <- lm(O3 ~ ., data=se, x=1)
> printh(summary(a))
===summary(a) 

Call:
lm(formula = O3 ~ ., data = se, x = 1)

Residuals:
     Min       1Q   Median       3Q      Max 
-12.1011  -2.9289  -0.2715   2.7080  13.3687 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 20.3135755 29.5193067   0.688  0.49186    
vh          -0.0054271  0.0053985  -1.005  0.31551    
wind        -0.0545832  0.1348425  -0.405  0.68590    
humidity     0.0809741  0.0188394   4.298 2.29e-05 ***
temp         0.2755492  0.0497912   5.534 6.52e-08 ***
ibh         -0.0002338  0.0002956  -0.791  0.42944    
dpg         -0.0033629  0.0112805  -0.298  0.76581    
ibt          0.0296411  0.0136088   2.178  0.03013 *  
vis         -0.0079910  0.0037503  -2.131  0.03387 *  
doy         -0.0091194  0.0027745  -3.287  0.00113 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 4.441 on 320 degrees of freedom
Multiple R-squared:  0.7012,	Adjusted R-squared:  0.6927 
F-statistic: 83.42 on 9 and 320 DF,  p-value: < 2.2e-16

> plotmo(a, trace=0, caption="getdata lm test2")
 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5
> a <- lm(O3 ~ ., data=se, y=1)
> printh(summary(a))
===summary(a) 

Call:
lm(formula = O3 ~ ., data = se, y = 1)

Residuals:
     Min       1Q   Median       3Q      Max 
-12.1011  -2.9289  -0.2715   2.7080  13.3687 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 20.3135755 29.5193067   0.688  0.49186    
vh          -0.0054271  0.0053985  -1.005  0.31551    
wind        -0.0545832  0.1348425  -0.405  0.68590    
humidity     0.0809741  0.0188394   4.298 2.29e-05 ***
temp         0.2755492  0.0497912   5.534 6.52e-08 ***
ibh         -0.0002338  0.0002956  -0.791  0.42944    
dpg         -0.0033629  0.0112805  -0.298  0.76581    
ibt          0.0296411  0.0136088   2.178  0.03013 *  
vis         -0.0079910  0.0037503  -2.131  0.03387 *  
doy         -0.0091194  0.0027745  -3.287  0.00113 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 4.441 on 320 degrees of freedom
Multiple R-squared:  0.7012,	Adjusted R-squared:  0.6927 
F-statistic: 83.42 on 9 and 320 DF,  p-value: < 2.2e-16

> plotmo(a, trace=0, caption="getdata lm test3")
 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5
> a <- lm(O3 ~ ., data=se, x=1, y=1)
> printh(summary(a))
===summary(a) 

Call:
lm(formula = O3 ~ ., data = se, x = 1, y = 1)

Residuals:
     Min       1Q   Median       3Q      Max 
-12.1011  -2.9289  -0.2715   2.7080  13.3687 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 20.3135755 29.5193067   0.688  0.49186    
vh          -0.0054271  0.0053985  -1.005  0.31551    
wind        -0.0545832  0.1348425  -0.405  0.68590    
humidity     0.0809741  0.0188394   4.298 2.29e-05 ***
temp         0.2755492  0.0497912   5.534 6.52e-08 ***
ibh         -0.0002338  0.0002956  -0.791  0.42944    
dpg         -0.0033629  0.0112805  -0.298  0.76581    
ibt          0.0296411  0.0136088   2.178  0.03013 *  
vis         -0.0079910  0.0037503  -2.131  0.03387 *  
doy         -0.0091194  0.0027745  -3.287  0.00113 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 4.441 on 320 degrees of freedom
Multiple R-squared:  0.7012,	Adjusted R-squared:  0.6927 
F-statistic: 83.42 on 9 and 320 DF,  p-value: < 2.2e-16

> plotmo(a, trace=0, caption="getdata lm test3")
 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5
> a <- lm(O3 ~ ., data=se, x=0, y=1, model=F)
> se <- 99
> expect.err(try(plotmo(a, trace=0, caption="getdata lm test4")), "cannot get the original model predictors")

Looked unsuccessfully for the original predictors in the following places:

(1) object$x: NULL

(2) model.frame: object 'O3' not found

(3) getCall(object)$x: less than three rows

Error : cannot get the original model predictors
Got expected error from try(plotmo(a, trace = 0, caption = "getdata lm test4"))
> se <- ozone1
> a <- lm(O3 ~ ., data=se, x=1, y=1)
> se <- 77
> printh(summary(a))
===summary(a) 

Call:
lm(formula = O3 ~ ., data = se, x = 1, y = 1)

Residuals:
     Min       1Q   Median       3Q      Max 
-12.1011  -2.9289  -0.2715   2.7080  13.3687 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 20.3135755 29.5193067   0.688  0.49186    
vh          -0.0054271  0.0053985  -1.005  0.31551    
wind        -0.0545832  0.1348425  -0.405  0.68590    
humidity     0.0809741  0.0188394   4.298 2.29e-05 ***
temp         0.2755492  0.0497912   5.534 6.52e-08 ***
ibh         -0.0002338  0.0002956  -0.791  0.42944    
dpg         -0.0033629  0.0112805  -0.298  0.76581    
ibt          0.0296411  0.0136088   2.178  0.03013 *  
vis         -0.0079910  0.0037503  -2.131  0.03387 *  
doy         -0.0091194  0.0027745  -3.287  0.00113 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 4.441 on 320 degrees of freedom
Multiple R-squared:  0.7012,	Adjusted R-squared:  0.6927 
F-statistic: 83.42 on 9 and 320 DF,  p-value: < 2.2e-16

> plotmo(a, trace=0, caption="getdata lm test5")
 plotmo grid:    vh wind humidity temp    ibh dpg   ibt vis   doy
               5760    5       64   62 2112.5  24 167.5 120 205.5
> se <- ozone1
> a <- lm(O3 ~ ., data=se, model=F)
> se$wind <- NULL
> expect.err(try(plotmo(a, trace=0, caption="getdata lm test6")), "cannot get the original model predictors")

Looked unsuccessfully for the original predictors in the following places:

(1) object$x: NULL

(2) model.frame: object 'wind' not found

(3) getCall(object)$x: NULL

Error : cannot get the original model predictors
Got expected error from try(plotmo(a, trace = 0, caption = "getdata lm test6"))
> 
> cat("test fixed.point warning in print.summary.earth\n")
test fixed.point warning in print.summary.earth
> options(digits=3)
> et <- etitanic
> et$age <- 1000 * et$age
> a <- earth(survived~., data=et)
> print(summary(a))
Call: earth(formula=survived~., data=et)

             coefficients
(Intercept)        1.0258
pclass2nd         -0.2165
pclass3rd         -0.3552
sexmale           -0.4903
h(11000-age)       0.0000
h(age-11000)       0.0000
h(sibsp-1)        -0.0926

Selected 7 of 10 terms, and 5 of 6 predictors
Termination condition: RSq changed by less than 0.001 at 10 terms
Importance: sexmale, pclass3rd, age, pclass2nd, sibsp, parch-unused
Number of terms at each degree of interaction: 1 6 (additive model)
GCV 0.152    RSS 155    GRSq 0.372    RSq 0.386
> print(summary(a, fixed.point=FALSE))
Call: earth(formula=survived~., data=et)

             coefficients
(Intercept)      1.03e+00
pclass2nd       -2.17e-01
pclass3rd       -3.55e-01
sexmale         -4.90e-01
h(11000-age)     2.92e-05
h(age-11000)    -4.45e-06
h(sibsp-1)      -9.26e-02

Selected 7 of 10 terms, and 5 of 6 predictors
Termination condition: RSq changed by less than 0.001 at 10 terms
Importance: sexmale, pclass3rd, age, pclass2nd, sibsp, parch-unused
Number of terms at each degree of interaction: 1 6 (additive model)
GCV 0.152    RSS 155    GRSq 0.372    RSq 0.386
> options(digits=7) # back to default
> 
> cat("--- summary earth with new data ----------------------\n")
--- summary earth with new data ----------------------
> a.trees <- earth(Volume~., data=trees)
> cat("summary(a.trees, newdata=trees)\n")
summary(a.trees, newdata=trees)
> print(summary(a.trees, newdata=trees))
RSq 0.974 on newdata (31 cases)
> cat("summary(a.trees, newdata=trees[1:5,])\n")
summary(a.trees, newdata=trees[1:5,])
> a.trees.summary <- print(summary(a.trees, newdata=trees[1:5,]))
RSq 0.919 on newdata (5 cases)
> 
> a.xy.trees <- earth(trees[,1:2], trees[,3])
> cat("summary(a.xy.trees, newdata=trees[1:5,])\n")
summary(a.xy.trees, newdata=trees[1:5,])
> a.xy.trees.summary <- print(summary(a.xy.trees, newdata=trees[1:5,]))
Assuming response trees[, 3] implies that the response column is  3
RSq 0.919 on newdata (5 cases)
> stopifnot(a.xy.trees.summary$newrsq == a.trees.summary$newrsq)
> 
> a.xy1.trees <- earth(trees[,1:2], trees$Volume)
> cat("summary(a.xy1.trees, newdata=trees[1:5,])\n")
summary(a.xy1.trees, newdata=trees[1:5,])
> a.xy1.trees.summary <- print(summary(a.xy1.trees, newdata=trees[1:5,]))
RSq 0.919 on newdata (5 cases)
> stopifnot(a.xy1.trees.summary$newrsq == a.trees.summary$newrsq)
> 
> cat("--- /a/r/earth/tests/test.earth.R -------------------------\n")
--- /a/r/earth/tests/test.earth.R -------------------------
> 
> options(options.old)
> source("../../tests/test.earth.R")
Call: earth(formula=Volume~., data=trees)

              coefficients
(Intercept)         29.060
h(14.2-Girth)       -3.420
h(Girth-14.2)        6.230
h(Height-75)         0.581

Selected 4 of 5 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 5 terms
Importance: Girth, Height
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 11.3    RSS 209    GRSq 0.96    RSq 0.974
x[31,2] with colnames Girth Height
y[31,1] with colname Volume, and values 10.3, 10.3, 10.2, 16.4, 18.8,...
Forward pass term 1, 2, 4
RSq changed by less than 0.001 at 3 terms (DeltaRSq 9.7e-05)
After forward pass GRSq 0.940 RSq 0.962
Prune backward penalty 2 nprune null: selected 3 of 3 terms, and 1 of 2 preds
After pruning pass GRSq 0.949 RSq 0.961
Call: earth(formula=Volume~., data=trees, trace=1, allowed=allowed.func)

              coefficients
(Intercept)          30.66
h(14.2-Girth)        -3.57
h(Girth-14.2)         6.76

Selected 3 of 3 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: Girth, Height-unused
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 14.3    RSS 313    GRSq 0.949    RSq 0.961
Call: earth(formula=Sepal.Length+Sepal.Width~Species, data=iris)

                  Sepal.Length Sepal.Width
(Intercept)               5.01       3.428
Speciesversicolor         0.93      -0.658
Speciesvirginica          1.58      -0.454

Selected 3 of 3 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: Speciesvirginica, Speciesversicolor
Number of terms at each degree of interaction: 1 2 (additive model)

               GCV  RSS  GRSq   RSq
Sepal.Length 0.278 39.0 0.597 0.619
Sepal.Width  0.121 17.0 0.367 0.401
All          0.399 55.9 0.547 0.571
> 
> cat("--- check that spurious warn gone: non-integer #successes in a binomial glm ---\n")
--- check that spurious warn gone: non-integer #successes in a binomial glm ---
> 
> library(segmented) # for down data
Loading required package: MASS
Loading required package: nlme
> data(down)
> fit.e <- earth(cases/births~age, data=down, weights=down$births, glm=list(family="binomial"))
> print(summary(fit.e))
Call: earth(formula=cases/births~age, data=down, weights=down$births,
            glm=list(family="binomial"))

GLM coefficients
            cases/births
(Intercept)       -6.943
h(age-36.5)        0.709
h(age-39.5)       -0.484

GLM (family binomial, link logit):
 nulldev df       dev df   devratio     AIC iters converged
     625 29      69.6 27       0.89     214     4         1

Earth selected 3 of 5 terms, and 1 of 1 predictors
Termination condition: RSq changed by less than 0.001 at 5 terms
Importance: age
Weights: 13555, 13675, 18752, 22005, 23896, 24667, 24807, 23986, 22860, ...
Number of terms at each degree of interaction: 1 2 (additive model)
Earth GCV 0.0124    RSS 0.259    GRSq 0.867    RSq 0.901
> 
> # test nk=1, 2, and 3
> cat("nk=1\n")
nk=1
> par(mfrow = c(2, 2), mar = c(3, 3, 3, 1), mgp = c(1.5, 0.5, 0))
> a.nk1 <- earth(Volume~., data=trees, nk=1)
> plot(a.nk1, which=1, main="nk=1")
> print(a.nk1)
Selected 1 of 1 terms, and 0 of 2 predictors
Termination condition: Reached nk 1
Importance: Girth-unused, Height-unused
Number of terms at each degree of interaction: 1 (intercept only model)
GCV 279    RSS 8106    GRSq 0    RSq 0
> cat("nk=2\n")
nk=2
> a.nk2 <- earth(Volume~., data=trees, nk=2)
> print(summary(a.nk2))
Call: earth(formula=Volume~., data=trees, nk=2)

            coefficients
(Intercept)         30.2

Selected 1 of 1 terms, and 0 of 2 predictors
Termination condition: Reached nk 2
Importance: Girth-unused, Height-unused
Number of terms at each degree of interaction: 1 (intercept only model)
GCV 279    RSS 8106    GRSq 0    RSq 0
> plot(a.nk2, which=1, main="nk=2")
> cat("nk=3\n")
nk=3
> a.nk3 <- earth(Volume~., data=trees, nk=3)
> plot(a.nk3, which=1, main="nk=3")
> 
> cat("\ntest model.matrix.earth\n")

test model.matrix.earth
> 
> check.model.matrix <- function(msg, xnew, bx1, bx2)
+ {
+     cat("check.model.matrix", msg, ":\n")
+     print(xnew)
+     if(!identical(bx1, bx2)) {
+        cat("\nnot identical\n")
+        cat(deparse(substitute(bx1)), ":\n", sep="")
+        print(bx1)
+        cat(deparse(substitute(bx2)), ":\n", sep="")
+        print(bx2)
+        stop("check.model.matrix ", msg, " failed")
+     }
+ }
> 
> data(trees)
> earth.trees.formula <- earth(Volume ~ ., data=trees, subset=1:20)
> bx <- model.matrix(earth.trees.formula)
> check.model.matrix("earth.trees.formula formula 1", NULL, bx, earth.trees.formula$bx)
check.model.matrix earth.trees.formula formula 1 :
NULL
> 
> # nprune so only Girth is used, not Height
> earth.girth.formula <- earth(Volume ~ ., data=trees, nprune=3)
> 
> # model.matrix where xnew is a data.frame
> 
> xnew <- trees[,1:2]
> bx <- model.matrix(earth.girth.formula, xnew)
> lm.mod <- lm(trees$Volume ~ bx[,-1])  # -1 to drop intercept
> stopifnot(coef(earth.girth.formula) == coef(lm.mod))
> 
> colnames(xnew) <- NULL
> bx <- model.matrix(earth.girth.formula, xnew)
> lm.mod2 <- lm(trees$Volume ~ bx[,-1])
> stopifnot(coef(earth.girth.formula) == coef(lm.mod2))
> 
> xnew <- data.frame(Girth=c(8.3, 8.6), Height=c(70, 65))
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 2", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 2 :
  Girth Height
1   8.3     70
2   8.6     65
> 
> # test what happens when variables are missing
> predict.girth.height <- predict(earth.girth.formula, xnew)
> predict.girth  <- predict(earth.girth.formula, newdata=data.frame(Girth=c(8.3, 8.6)))
> stopifnot(all.equal(predict.girth.height, predict.girth))
> predict.height <- predict(earth.girth.formula, newdata=data.frame(Height=c(70, 65)))
> stopifnot(all(is.na(predict.height)))
> 
> xnew <- trees[1:2,]
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 3", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 3 :
  Girth Height Volume
1   8.3     70   10.3
2   8.6     65   10.3
> 
> xnew <- trees[1:2,1:2] # exclude Volume column
> colnames(xnew) <- NULL
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 4", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 4 :
        
1 8.3 70
2 8.6 65
> 
> xnew <- trees[1:2,3:1] # change order of columns
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 5", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 5 :
  Volume Height Girth
1   10.3     70   8.3
2   10.3     65   8.6
> 
> xnew <- trees[1:2,1,drop=FALSE]  # include only Girth
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 6", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 6 :
  Girth
1   8.3
2   8.6
> 
> xnew <- trees[1,2:1]
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 7", xnew, bx, earth.girth.formula$bx[1,,drop=FALSE])
check.model.matrix earth.girth.formula formula 7 :
  Height Girth
1     70   8.3
> 
> xnew <- trees[1,1:2]
> names(xnew) <- NULL
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 8", xnew, bx, earth.girth.formula$bx[1,,drop=FALSE])
check.model.matrix earth.girth.formula formula 8 :
        
1 8.3 70
> 
> # model.matrix where xnew is a matrix (same as above code but with as.matrix)
> 
> xnew <- as.matrix(trees[,1:2])
> bx <- model.matrix(earth.girth.formula, xnew)
> lm.mod <- lm(trees$Volume ~ bx[,-1])  # -1 to drop intercept
> stopifnot(coef(earth.girth.formula) == coef(lm.mod))
> 
> colnames(xnew) <- NULL
> bx <- model.matrix(earth.girth.formula, xnew)
> lm.mod2 <- lm(trees$Volume ~ bx[,-1])
> stopifnot(coef(earth.girth.formula) == coef(lm.mod2))
> 
> xnew <- as.matrix(data.frame(Girth=c(8.3, 8.6), Height=c(70, 65)))
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 9", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 9 :
     Girth Height
[1,]   8.3     70
[2,]   8.6     65
> 
> xnew <- as.matrix(trees[1:2,])
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 10", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 10 :
  Girth Height Volume
1   8.3     70   10.3
2   8.6     65   10.3
> 
> xnew <- as.matrix(trees[1:2,1:2]) # exclude Volume column
> colnames(xnew) <- NULL
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 11", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 11 :
  [,1] [,2]
1  8.3   70
2  8.6   65
> 
> xnew <- as.matrix(trees[1:2,3:1]) # change order of columns
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 12", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 12 :
  Volume Height Girth
1   10.3     70   8.3
2   10.3     65   8.6
> 
> xnew <- as.matrix(trees[1:2,1,drop=FALSE]) # include only Girth
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 13", xnew, bx, earth.girth.formula$bx[1:2,])
check.model.matrix earth.girth.formula formula 13 :
  Girth
1   8.3
2   8.6
> 
> xnew <- as.matrix(trees[1,2:1])
> bx <- model.matrix(earth.girth.formula, xnew, trace=2)
get.earth.x from model.matrix.earth: x columns are in the wrong order, correcting the column order
    Old columns: Height Girth
    New columns: Girth Height
get.earth.x from model.matrix.earth: x[1,2]:
  Girth Height
1   8.3     70

get.earth.x from model.matrix.earth: after call to model.frame: mf[1,2]:
  Girth Height
1   8.3     70

> check.model.matrix("earth.girth.formula formula 14", xnew, bx, earth.girth.formula$bx[1,,drop=FALSE])
check.model.matrix earth.girth.formula formula 14 :
  Height Girth
1     70   8.3
> 
> xnew <- as.matrix(trees[3,1:2])
> names(xnew) <- NULL
> bx <- model.matrix(earth.girth.formula, xnew)
> check.model.matrix("earth.girth.formula formula 15", xnew, bx, earth.girth.formula$bx[3,,drop=FALSE])
check.model.matrix earth.girth.formula formula 15 :
  Girth Height
3   8.8     63
> 
> #--- model.matrix with an x,y model
> 
> data(trees)
> earth.trees.xy.subset <- earth(trees[,1:2], trees[,3], subset=1:20)
> bx <- model.matrix(earth.trees.xy.subset)
> check.model.matrix("earth.trees.xy.subset x,y 1", NULL, bx, earth.trees.xy.subset$bx)
check.model.matrix earth.trees.xy.subset x,y 1 :
NULL
> 
> # nprune so only Girth is used, not Height
> earth.girth.xy <- earth(trees[,1:2], trees[,3], nprune=3)
> 
> # model.matrix where xnew is a data.frame
> 
> xnew <- trees[,1:2]
> bx <- model.matrix(earth.girth.xy, xnew)
> lm.mod <- lm(trees$Volume ~ bx[,-1])  # -1 to drop intercept
> stopifnot(coef(earth.girth.xy) == coef(lm.mod))
> 
> colnames(xnew) <- NULL
> bx <- model.matrix(earth.girth.xy, xnew)
> lm.mod2 <- lm(trees$Volume ~ bx[,-1])
> stopifnot(coef(earth.girth.xy) == coef(lm.mod2))
> 
> xnew <- data.frame(Girth=c(8.3, 8.6), Height=c(70, 65))
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 2", xnew, bx, earth.girth.xy$bx[1:2,])
check.model.matrix earth.girth.xy x,y 2 :
  Girth Height
1   8.3     70
2   8.6     65
> 
> # test what happens when variables are missing
> predict.girth.height <- predict(earth.girth.xy, xnew)
> predict.girth  <- predict(earth.girth.xy, newdata=data.frame(Girth=c(8.3, 8.6)))
> stopifnot(all.equal(predict.girth.height, predict.girth))
> predict.height <- predict(earth.girth.xy, newdata=data.frame(Height=c(70, 65)))
> stopifnot(all(is.na(predict.height)))
> 
> xnew <- trees[1:2,]
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 3", xnew, bx, earth.girth.xy$bx[1:2,])
check.model.matrix earth.girth.xy x,y 3 :
  Girth Height Volume
1   8.3     70   10.3
2   8.6     65   10.3
> 
> xnew <- trees[1:2,1:2] # exclude Volume column
> colnames(xnew) <- NULL
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 4", xnew, bx, earth.girth.xy$bx[1:2,])
check.model.matrix earth.girth.xy x,y 4 :
        
1 8.3 70
2 8.6 65
> 
> # # TODO fails
> # xnew <- trees[1:2,3:1] # change order of columns
> # bx <- model.matrix(earth.girth.xy, xnew)
> # check.model.matrix("earth.girth.xy x,y 5", xnew, bx, earth.girth.xy$bx[1:2,])
> 
> xnew <- trees[1:2,1,drop=FALSE]  # include only Girth
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 6", xnew, bx, earth.girth.xy$bx[1:2,])
check.model.matrix earth.girth.xy x,y 6 :
  Girth
1   8.3
2   8.6
> 
> xnew <- trees[1,2:1]
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 7", xnew, bx, earth.girth.xy$bx[1,,drop=FALSE])
check.model.matrix earth.girth.xy x,y 7 :
  Height Girth
1     70   8.3
> 
> xnew <- trees[1,1:2]
> names(xnew) <- NULL
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 8", xnew, bx, earth.girth.xy$bx[1,,drop=FALSE])
check.model.matrix earth.girth.xy x,y 8 :
        
1 8.3 70
> 
> # model.matrix where xnew is a matrix (same as above code but with as.matrix)
> 
> xnew <- as.matrix(trees[,1:2])
> bx <- model.matrix(earth.girth.xy, xnew)
> lm.mod <- lm(trees$Volume ~ bx[,-1])  # -1 to drop intercept
> stopifnot(coef(earth.girth.xy) == coef(lm.mod))
> 
> colnames(xnew) <- NULL
> bx <- model.matrix(earth.girth.xy, xnew)
> lm.mod2 <- lm(trees$Volume ~ bx[,-1])
> stopifnot(coef(earth.girth.xy) == coef(lm.mod2))
> 
> xnew <- as.matrix(data.frame(Girth=c(8.3, 8.6), Height=c(70, 65)))
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 9", xnew, bx, earth.girth.xy$bx[1:2,])
check.model.matrix earth.girth.xy x,y 9 :
     Girth Height
[1,]   8.3     70
[2,]   8.6     65
> 
> xnew <- as.matrix(trees[1:2,])
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 10", xnew, bx, earth.girth.xy$bx[1:2,])
check.model.matrix earth.girth.xy x,y 10 :
  Girth Height Volume
1   8.3     70   10.3
2   8.6     65   10.3
> 
> xnew <- as.matrix(trees[1:2,1:2]) # exclude Volume column
> colnames(xnew) <- NULL
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 11", xnew, bx, earth.girth.xy$bx[1:2,])
check.model.matrix earth.girth.xy x,y 11 :
  [,1] [,2]
1  8.3   70
2  8.6   65
> 
> # # TODO fails
> # xnew <- as.matrix(trees[1:2,3:1]) # change order of columns
> # bx <- model.matrix(earth.girth.xy, xnew)
> # check.model.matrix("earth.girth.xy x,y 12", xnew, bx, earth.girth.xy$bx[1:2,])
> 
> xnew <- as.matrix(trees[1:2,1,drop=FALSE]) # include only Girth
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 13", xnew, bx, earth.girth.xy$bx[1:2,])
check.model.matrix earth.girth.xy x,y 13 :
  Girth
1   8.3
2   8.6
> 
> xnew <- as.matrix(trees[1,2:1])
> bx <- model.matrix(earth.girth.xy, xnew, trace=2)
get.earth.x from model.matrix.earth: x columns are in the wrong order, correcting the column order
    Old columns: Height Girth
    New columns: Girth Height
get.earth.x from model.matrix.earth: x[1,2]:
  Girth Height
1   8.3     70

> check.model.matrix("earth.girth.xy x,y 14", xnew, bx, earth.girth.xy$bx[1,,drop=FALSE])
check.model.matrix earth.girth.xy x,y 14 :
  Height Girth
1     70   8.3
> 
> xnew <- as.matrix(trees[3,1:2])
> names(xnew) <- NULL
> bx <- model.matrix(earth.girth.xy, xnew)
> check.model.matrix("earth.girth.xy x,y 15", xnew, bx, earth.girth.xy$bx[3,,drop=FALSE])
check.model.matrix earth.girth.xy x,y 15 :
  Girth Height
3   8.8     63
> 
> cat("--- example in earth vignette \"How do I get p values for earth model coefficients?\" ---\n")
--- example in earth vignette "How do I get p values for earth model coefficients?" ---
> 
> earth.mod <- earth(Volume~., data=trees) # standard earth model
> bx <- earth.mod$bx[,-1]                  # earth model's basis mat (-1 to drop intercept)
> bx <- as.data.frame(bx)                  # lm requires a data frame
> bx$Volume <- trees$Volume                # add Volume to data
> lm.mod <- lm(Volume~., data=bx)          # standard linear regression on earth's basis mat
> summary(lm.mod)                          # prints p values

Call:
lm(formula = Volume ~ ., data = bx)

Residuals:
   Min     1Q Median     3Q    Max 
-4.977 -2.178  0.083  1.376  5.371 

Coefficients:
                Estimate Std. Error t value Pr(>|t|)    
(Intercept)       29.060      1.073   27.07  < 2e-16 ***
`h(Girth-14.2)`    6.230      0.390   15.99  2.7e-15 ***
`h(14.2-Girth)`   -3.420      0.331  -10.32  7.2e-11 ***
`h(Height-75)`     0.581      0.159    3.66   0.0011 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.78 on 27 degrees of freedom
Multiple R-squared:  0.974,	Adjusted R-squared:  0.971 
F-statistic:  340 on 3 and 27 DF,  p-value: <2e-16

> 
> remove(earth.mod, bx, lm.mod) # tidy up
> 
> cat("--- examples in model.matrix.earth.Rd ---------------------------------------\n")
--- examples in model.matrix.earth.Rd ---------------------------------------
> 
> # Example 1
> data(trees)
> earth.mod <- earth(Volume ~ ., data = trees) # standard earth model
> summary(earth.mod, decomp = "none")   # "none" to print terms in same order as lm.mod below
Call: earth(formula=Volume~., data=trees)

              coefficients
(Intercept)         29.060
h(Girth-14.2)        6.230
h(14.2-Girth)       -3.420
h(Height-75)         0.581

Selected 4 of 5 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 5 terms
Importance: Girth, Height
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 11.3    RSS 209    GRSq 0.96    RSq 0.974
> 
> bx <- model.matrix(earth.mod)         # equivalent to bx <- earth.mod$bx
> lm.mod <- lm(trees$Volume ~ bx[,-1])  # -1 to drop intercept
> summary(lm.mod)                       # yields same coeffs as above summary

Call:
lm(formula = trees$Volume ~ bx[, -1])

Residuals:
   Min     1Q Median     3Q    Max 
-4.977 -2.178  0.083  1.376  5.371 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)    
(Intercept)             29.060      1.073   27.07  < 2e-16 ***
bx[, -1]h(Girth-14.2)    6.230      0.390   15.99  2.7e-15 ***
bx[, -1]h(14.2-Girth)   -3.420      0.331  -10.32  7.2e-11 ***
bx[, -1]h(Height-75)     0.581      0.159    3.66   0.0011 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.78 on 27 degrees of freedom
Multiple R-squared:  0.974,	Adjusted R-squared:  0.971 
F-statistic:  340 on 3 and 27 DF,  p-value: <2e-16

>                                       # displayed t values are not meaningful
> 
> # Example 2
> earth.mod <- earth(Volume~., data=trees) # standard earth model
> summary(earth.mod, decomp = "none") # "none" to print terms in same order as lm.mod below
Call: earth(formula=Volume~., data=trees)

              coefficients
(Intercept)         29.060
h(Girth-14.2)        6.230
h(14.2-Girth)       -3.420
h(Height-75)         0.581

Selected 4 of 5 terms, and 2 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 5 terms
Importance: Girth, Height
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 11.3    RSS 209    GRSq 0.96    RSq 0.974
> bx <- model.matrix(earth.mod)       # earth model's basis mat (equivalent to bx <- earth.mod$bx)
> bx <- bx[, -1, drop=FALSE]          # -1 to drop intercept
> bx <- as.data.frame(bx)             # lm requires a data frame
> bx$Volume <- trees$Volume           # add Volume to data
> lm.mod <- lm(Volume~., data=bx)     # standard linear regression on earth's basis mat
> summary(lm.mod)                     # yields same coeffs as above summary

Call:
lm(formula = Volume ~ ., data = bx)

Residuals:
   Min     1Q Median     3Q    Max 
-4.977 -2.178  0.083  1.376  5.371 

Coefficients:
                Estimate Std. Error t value Pr(>|t|)    
(Intercept)       29.060      1.073   27.07  < 2e-16 ***
`h(Girth-14.2)`    6.230      0.390   15.99  2.7e-15 ***
`h(14.2-Girth)`   -3.420      0.331  -10.32  7.2e-11 ***
`h(Height-75)`     0.581      0.159    3.66   0.0011 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.78 on 27 degrees of freedom
Multiple R-squared:  0.974,	Adjusted R-squared:  0.971 
F-statistic:  340 on 3 and 27 DF,  p-value: <2e-16

>                                     # displayed t values are not meaningful
> 
> remove(earth.mod, bx, lm.mod) # tidy up
> 
> cat("--- compare backward, none, exhaustive, forward, seqrep ---------------------\n")
--- compare backward, none, exhaustive, forward, seqrep ---------------------
> data(ozone1)
> oz <- ozone1[1:50,]
> cat("--mod.none\n")
--mod.none
> mod.none <- earth(O3~., data=oz, degree=2, trace=4, pmethod="none")
Call: earth(formula=O3~., data=oz, pmethod="none", trace=4, degree=2)

x[50,9]:
      vh wind humidity temp  ibh dpg ibt vis doy
1   5710    4       28   40 2693 -25  87 250  33
2   5700    3       37   45  590 -24 128 100  34
3   5760    3       51   54 1450  25 139  60  35
... 5720    4       69   35 1568  15 121  60  36
50  5640    5       68   50 5000  24  56 300  84

y[50,1]:
    O3
1    3
2    5
3    5
...  6
50   6

Forward pass: minspan 5 endspan 10   x[50,9] 3.52 kB   bx[50,21] 8.2 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0507 0.2345       0.2345    7          ibt         174  2   3         1 
4      0.1107 0.4367       0.2021    9          doy          45  4   5         1 
6      0.1332 0.5826        0.146    3     humidity          28  6   7         1 
8      0.0724 0.6751      0.09244    1           vh        5720  8   9         1 
10     0.1641 0.7555      0.08043    1           vh        5350< 10        6   2 
12     0.1705 0.8010      0.04548    9          doy          61  11            1 
14    -0.0529 0.8417      0.04069    2         wind           4  12  13        1 
16    -0.1680 0.8676      0.02587    4         temp          30< 14        5   2 
18    -1.0243 0.8885      0.02094    6          dpg          -2  15  16        1 
20    -4.1102 0.9101      0.02157    4         temp          51  17  18        1 final (reached nk 21)

Reached nk 21
After forward pass GRSq -4.110 RSq 0.910
Forward pass complete: 21 terms, 18 terms used

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2     -0.0643  0.0415    -0.0643      1  1 2
          3      0.3274  0.4577     0.3917      2  1 6 10
          4      0.2845  0.4867    -0.0429      3  1 4 6 10
          5      0.4261  0.6365     0.1417      3  1 4 6 10 11
          6      0.4967  0.7207     0.0706      3  1 4 6 9 10 11
          7      0.5304  0.7739     0.0337      4  1 4 6 9 10 11 13
          8      0.5260  0.8041    -0.0044      5  1 4 6 9 10 11 13 15
          9      0.4962  0.8235    -0.0298      5  1 4 6 9 10 11 13 15 16
         10      0.4844  0.8492    -0.0119      5  1 4 6 8 9 10 11 13 15 16
         11      0.4031  0.8568    -0.0813      6  1 4 6 8 9 10 11 13 14 15 16
         12      0.2946  0.8642    -0.1085      6  1 4 5 6 8 9 10 11 13 14 15 16
         13      0.1833  0.8772    -0.1113      6  1 4 5 6 8 9 10 11 13 14 15 16 18
         14      0.0300  0.8900    -0.1533      6  1 4 5 6 8 9 10 11 13 14 15 16 17 18
         15     -0.2295  0.8996    -0.2595      6  1 4 5 6 7 8 9 10 11 13 14 15 16 17 18
         16     -0.7245  0.9050    -0.4950      6  1 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
         17     -1.7229  0.9081    -0.9984      7  1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
chosen   18     -4.1102  0.9101    -2.3873      7  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Prune none penalty 3 nprune null: selected 18 of 18 terms, and 7 of 9 preds
After pruning pass GRSq -4.11 RSq 0.91
> print(summary(mod.none))
Call: earth(formula=O3~., data=oz, pmethod="none", trace=4, degree=2)

                    coefficients
(Intercept)                5.325
h(5720-vh)                 0.041
h(vh-5720)                 0.024
h(4-wind)                  1.482
h(wind-4)                  0.155
h(28-humidity)            -0.139
h(humidity-28)            -7.705
h(51-temp)                -0.132
h(temp-51)                -0.104
h(-2-dpg)                 -0.033
h(dpg- -2)                -0.023
h(174-ibt)                -0.006
h(ibt-174)                -0.013
h(45-doy)                  1.279
h(doy-45)                  0.173
h(doy-61)                 -0.268
vh * h(humidity-28)        0.001
temp * h(45-doy)          -0.030

Selected 18 of 18 terms, and 7 of 9 predictors (pmethod="none")
Termination condition: Reached nk 21
Importance: vh, humidity, doy, wind, dpg, temp, ibt, ibh-unused, ...
Number of terms at each degree of interaction: 1 15 2
GCV 35    RSS 29.6    GRSq -4.11    RSq 0.91
> cat("--mod.backward\n")
--mod.backward
> mod.backward <- earth(O3~., data=oz, degree=2, trace=4, pmethod="backward")
Call: earth(formula=O3~., data=oz, pmethod="backward", trace=4, degree=2)

x[50,9]:
      vh wind humidity temp  ibh dpg ibt vis doy
1   5710    4       28   40 2693 -25  87 250  33
2   5700    3       37   45  590 -24 128 100  34
3   5760    3       51   54 1450  25 139  60  35
... 5720    4       69   35 1568  15 121  60  36
50  5640    5       68   50 5000  24  56 300  84

y[50,1]:
    O3
1    3
2    5
3    5
...  6
50   6

Forward pass: minspan 5 endspan 10   x[50,9] 3.52 kB   bx[50,21] 8.2 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0507 0.2345       0.2345    7          ibt         174  2   3         1 
4      0.1107 0.4367       0.2021    9          doy          45  4   5         1 
6      0.1332 0.5826        0.146    3     humidity          28  6   7         1 
8      0.0724 0.6751      0.09244    1           vh        5720  8   9         1 
10     0.1641 0.7555      0.08043    1           vh        5350< 10        6   2 
12     0.1705 0.8010      0.04548    9          doy          61  11            1 
14    -0.0529 0.8417      0.04069    2         wind           4  12  13        1 
16    -0.1680 0.8676      0.02587    4         temp          30< 14        5   2 
18    -1.0243 0.8885      0.02094    6          dpg          -2  15  16        1 
20    -4.1102 0.9101      0.02157    4         temp          51  17  18        1 final (reached nk 21)

Reached nk 21
After forward pass GRSq -4.110 RSq 0.910
Forward pass complete: 21 terms, 18 terms used

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2     -0.0643  0.0415    -0.0643      1  1 2
          3      0.3274  0.4577     0.3917      2  1 6 10
          4      0.2845  0.4867    -0.0429      3  1 4 6 10
          5      0.4261  0.6365     0.1417      3  1 4 6 10 11
          6      0.4967  0.7207     0.0706      3  1 4 6 9 10 11
chosen    7      0.5304  0.7739     0.0337      4  1 4 6 9 10 11 13
          8      0.5260  0.8041    -0.0044      5  1 4 6 9 10 11 13 15
          9      0.4962  0.8235    -0.0298      5  1 4 6 9 10 11 13 15 16
         10      0.4844  0.8492    -0.0119      5  1 4 6 8 9 10 11 13 15 16
         11      0.4031  0.8568    -0.0813      6  1 4 6 8 9 10 11 13 14 15 16
         12      0.2946  0.8642    -0.1085      6  1 4 5 6 8 9 10 11 13 14 15 16
         13      0.1833  0.8772    -0.1113      6  1 4 5 6 8 9 10 11 13 14 15 16 18
         14      0.0300  0.8900    -0.1533      6  1 4 5 6 8 9 10 11 13 14 15 16 17 18
         15     -0.2295  0.8996    -0.2595      6  1 4 5 6 7 8 9 10 11 13 14 15 16 17 18
         16     -0.7245  0.9050    -0.4950      6  1 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
         17     -1.7229  0.9081    -0.9984      7  1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
         18     -4.1102  0.9101    -2.3873      7  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Prune backward penalty 3 nprune null: selected 7 of 18 terms, and 4 of 9 preds
After pruning pass GRSq 0.53 RSq 0.774
> print(summary(mod.backward))
Call: earth(formula=O3~., data=oz, pmethod="backward", trace=4, degree=2)

                    coefficients
(Intercept)                3.446
h(5720-vh)                 0.041
h(4-wind)                  1.108
h(humidity-28)            -8.941
h(doy-45)                  0.204
h(doy-61)                 -0.334
vh * h(humidity-28)        0.002

Selected 7 of 18 terms, and 4 of 9 predictors
Termination condition: Reached nk 21
Importance: vh, humidity, doy, wind, ibt-unused, temp-unused, ibh-unused, ...
Number of terms at each degree of interaction: 1 5 1
GCV 3.22    RSS 74.4    GRSq 0.53    RSq 0.774
> cat("--mod.forward\n")
--mod.forward
> mod.forward <- earth(O3~., data=oz, degree=2, trace=4, pmethod="forward")
Call: earth(formula=O3~., data=oz, pmethod="forward", trace=4, degree=2)

x[50,9]:
      vh wind humidity temp  ibh dpg ibt vis doy
1   5710    4       28   40 2693 -25  87 250  33
2   5700    3       37   45  590 -24 128 100  34
3   5760    3       51   54 1450  25 139  60  35
... 5720    4       69   35 1568  15 121  60  36
50  5640    5       68   50 5000  24  56 300  84

y[50,1]:
    O3
1    3
2    5
3    5
...  6
50   6

Forward pass: minspan 5 endspan 10   x[50,9] 3.52 kB   bx[50,21] 8.2 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0507 0.2345       0.2345    7          ibt         174  2   3         1 
4      0.1107 0.4367       0.2021    9          doy          45  4   5         1 
6      0.1332 0.5826        0.146    3     humidity          28  6   7         1 
8      0.0724 0.6751      0.09244    1           vh        5720  8   9         1 
10     0.1641 0.7555      0.08043    1           vh        5350< 10        6   2 
12     0.1705 0.8010      0.04548    9          doy          61  11            1 
14    -0.0529 0.8417      0.04069    2         wind           4  12  13        1 
16    -0.1680 0.8676      0.02587    4         temp          30< 14        5   2 
18    -1.0243 0.8885      0.02094    6          dpg          -2  15  16        1 
20    -4.1102 0.9101      0.02157    4         temp          51  17  18        1 final (reached nk 21)

Reached nk 21
After forward pass GRSq -4.110 RSq 0.910
Forward pass complete: 21 terms, 18 terms used

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2      0.1478  0.2325     0.1478      1  1 3
          3      0.2867  0.4248     0.1389      2  1 3 4
chosen    4      0.4118  0.5781     0.1251      3  1 3 4 7
          5      0.3946  0.6165    -0.0172      4  1 3 4 7 13
          6      0.3715  0.6513    -0.0231      5  1 3 4 7 13 16
          7      0.3424  0.6834    -0.0292      6  1 3 4 7 13 16 9
          8      0.2960  0.7091    -0.0463      7  1 3 4 7 13 16 9 14
          9      0.2253  0.7287    -0.0707      7  1 3 4 7 13 16 9 14 5
         10      0.1641  0.7555    -0.0612      4  1 2 3 4 5 6 7 8 9 10
         11      0.1705  0.8010     0.0064      4  1 2 3 4 5 6 7 8 9 10 11
         12     -0.0334  0.8010    -0.2039      5  1 2 3 4 5 6 7 8 9 10 11 12
         13      0.0121  0.8515     0.0455      7  1 3 4 7 13 16 9 14 5 8 15 10 6
         14     -0.0753  0.8781    -0.0874      7  1 3 4 7 13 16 9 14 5 8 15 10 6 11
         15     -0.3788  0.8874    -0.3035      7  1 3 4 7 13 16 9 14 5 8 15 10 6 11 17
         16     -0.8136  0.9001    -0.4348      7  1 3 4 7 13 16 9 14 5 8 15 10 6 11 17 18
         17     -1.7890  0.9059    -0.9754      7  1 3 4 7 13 16 9 14 5 8 15 10 6 11 17 18 12
         18     -4.1102  0.9101    -2.3212      7  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Prune forward penalty 3 nprune null: selected 4 of 18 terms, and 3 of 9 preds
After pruning pass GRSq 0.412 RSq 0.578
> print(summary(mod.forward))
Call: earth(formula=O3~., data=oz, pmethod="forward", trace=4, degree=2)

               coefficients
(Intercept)           7.496
h(28-humidity)       -0.266
h(174-ibt)           -0.046
h(doy-45)             0.110

Selected 4 of 18 terms, and 3 of 9 predictors (pmethod="forward")
Termination condition: Reached nk 21
Importance: ibt, doy, humidity, vh-unused, wind-unused, temp-unused, ...
Number of terms at each degree of interaction: 1 3 (additive model)
GCV 4.03    RSS 139    GRSq 0.412    RSq 0.578
> cat("--mod.exhaustive\n")
--mod.exhaustive
> mod.exhaustive <- earth(O3~., data=oz, degree=2, trace=4, pmethod="exhaustive")
Call: earth(formula=O3~., data=oz, pmethod="exhaustive", trace=4, degree=2)

x[50,9]:
      vh wind humidity temp  ibh dpg ibt vis doy
1   5710    4       28   40 2693 -25  87 250  33
2   5700    3       37   45  590 -24 128 100  34
3   5760    3       51   54 1450  25 139  60  35
... 5720    4       69   35 1568  15 121  60  36
50  5640    5       68   50 5000  24  56 300  84

y[50,1]:
    O3
1    3
2    5
3    5
...  6
50   6

Forward pass: minspan 5 endspan 10   x[50,9] 3.52 kB   bx[50,21] 8.2 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0507 0.2345       0.2345    7          ibt         174  2   3         1 
4      0.1107 0.4367       0.2021    9          doy          45  4   5         1 
6      0.1332 0.5826        0.146    3     humidity          28  6   7         1 
8      0.0724 0.6751      0.09244    1           vh        5720  8   9         1 
10     0.1641 0.7555      0.08043    1           vh        5350< 10        6   2 
12     0.1705 0.8010      0.04548    9          doy          61  11            1 
14    -0.0529 0.8417      0.04069    2         wind           4  12  13        1 
16    -0.1680 0.8676      0.02587    4         temp          30< 14        5   2 
18    -1.0243 0.8885      0.02094    6          dpg          -2  15  16        1 
20    -4.1102 0.9101      0.02157    4         temp          51  17  18        1 final (reached nk 21)

Reached nk 21
After forward pass GRSq -4.110 RSq 0.910
Forward pass complete: 21 terms, 18 terms used

Exhaustive pruning: number of subsets 262143   bx sing val ratio 6.6e-07
Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2      0.1478  0.2325     0.1478      1  1 3
          3      0.3274  0.4577     0.1796      2  1 6 10
          4      0.4118  0.5781     0.0844      3  1 4 7 3
          5      0.4261  0.6365     0.0143      3  1 6 11 4 10
          6      0.4967  0.7207     0.0706      3  1 6 9 4 11 10
chosen    7      0.5304  0.7739     0.0337      4  1 6 9 4 11 10 13
          8      0.5260  0.8041    -0.0044      5  1 6 15 11 10 13 9 4
          9      0.4962  0.8235    -0.0298      5  1 6 15 11 10 13 9 16 4
         10      0.4844  0.8492    -0.0119      5  1 6 8 13 15 10 11 4 16 9
         11      0.4031  0.8568    -0.0813      6  1 14 16 15 6 13 4 10 9 8 11
         12      0.3006  0.8654    -0.1025      6  1 14 16 15 6 13 4 10 9 8 11 17
         13      0.1833  0.8772    -0.1174      6  1 14 16 15 6 13 4 10 9 18 11 5 8
         14      0.0300  0.8900    -0.1533      6  1 14 16 15 6 13 4 10 9 18 17 8 11 5
         15     -0.2295  0.8996    -0.2595      6  1 14 16 15 6 13 4 10 9 18 17 8 7 5 11
         16     -0.7245  0.9050    -0.4950      6  1 14 16 15 6 13 4 10 9 18 17 8 7 5 12 11
         17     -1.7229  0.9081    -0.9984      7  1 2 11 6 8 12 18 9 14 7 13 10 15 17 5 16 4
         18     -4.1102  0.9101    -2.3873      7  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Prune exhaustive penalty 3 nprune null: selected 7 of 18 terms, and 4 of 9 preds
After pruning pass GRSq 0.53 RSq 0.774
> print(summary(mod.exhaustive))
Call: earth(formula=O3~., data=oz, pmethod="exhaustive", trace=4, degree=2)

                    coefficients
(Intercept)                3.446
h(5720-vh)                 0.041
h(4-wind)                  1.108
h(humidity-28)            -8.941
h(doy-45)                  0.204
h(doy-61)                 -0.334
vh * h(humidity-28)        0.002

Selected 7 of 18 terms, and 4 of 9 predictors (pmethod="exhaustive")
Termination condition: Reached nk 21
Importance: humidity, vh, doy, ibt-unused, wind, temp-unused, ibh-unused, ...
Number of terms at each degree of interaction: 1 5 1
GCV 3.22    RSS 74.4    GRSq 0.53    RSq 0.774
> cat("--mod.seqrep\n")
--mod.seqrep
> mod.seqrep <- earth(O3~., data=oz, degree=2, trace=4, pmethod="seqrep")
Call: earth(formula=O3~., data=oz, pmethod="seqrep", trace=4, degree=2)

x[50,9]:
      vh wind humidity temp  ibh dpg ibt vis doy
1   5710    4       28   40 2693 -25  87 250  33
2   5700    3       37   45  590 -24 128 100  34
3   5760    3       51   54 1450  25 139  60  35
... 5720    4       69   35 1568  15 121  60  36
50  5640    5       68   50 5000  24  56 300  84

y[50,1]:
    O3
1    3
2    5
3    5
...  6
50   6

Forward pass: minspan 5 endspan 10   x[50,9] 3.52 kB   bx[50,21] 8.2 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0507 0.2345       0.2345    7          ibt         174  2   3         1 
4      0.1107 0.4367       0.2021    9          doy          45  4   5         1 
6      0.1332 0.5826        0.146    3     humidity          28  6   7         1 
8      0.0724 0.6751      0.09244    1           vh        5720  8   9         1 
10     0.1641 0.7555      0.08043    1           vh        5350< 10        6   2 
12     0.1705 0.8010      0.04548    9          doy          61  11            1 
14    -0.0529 0.8417      0.04069    2         wind           4  12  13        1 
16    -0.1680 0.8676      0.02587    4         temp          30< 14        5   2 
18    -1.0243 0.8885      0.02094    6          dpg          -2  15  16        1 
20    -4.1102 0.9101      0.02157    4         temp          51  17  18        1 final (reached nk 21)

Reached nk 21
After forward pass GRSq -4.110 RSq 0.910
Forward pass complete: 21 terms, 18 terms used

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2      0.1478  0.2325     0.1478      1  1 3
          3      0.2867  0.4248     0.1389      2  1 3 4
          4      0.4118  0.5781     0.1251      3  1 4 3 7
chosen    5      0.4131  0.6282     0.0013      4  1 13 3 4 16
          6      0.3744  0.6528    -0.0388      5  1 16 13 4 3 9
          7      0.1332  0.5826    -0.2412      3  1 2 3 4 5 6 7
          8      0.2960  0.7091     0.1629      7  1 9 13 4 3 16 7 14
          9      0.2253  0.7287    -0.0707      7  1 14 7 4 3 9 13 16 5
         10      0.1641  0.7555    -0.0612      4  1 2 3 4 5 6 7 8 9 10
         11      0.1705  0.8010     0.0064      4  1 2 3 4 5 6 7 8 9 10 11
         12      0.1955  0.8451     0.0251      6  1 6 9 13 16 14 5 8 15 7 10 18
         13      0.1833  0.8772    -0.0123      6  1 4 10 18 6 15 9 13 16 14 5 8 11
         14      0.0300  0.8900    -0.1533      6  1 16 5 9 13 8 10 18 6 4 11 14 15 17
         15     -0.5442  0.8739    -0.5742      7  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
         16     -1.0243  0.8885    -0.4801      7  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
         17     -1.7229  0.9081    -0.6986      7  1 17 5 9 13 8 10 18 6 4 11 14 15 16 7 12 2
         18     -4.1102  0.9101    -2.3873      7  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Prune seqrep penalty 3 nprune null: selected 5 of 18 terms, and 4 of 9 preds
After pruning pass GRSq 0.413 RSq 0.628
> print(summary(mod.seqrep))
Call: earth(formula=O3~., data=oz, pmethod="seqrep", trace=4, degree=2)

            coefficients
(Intercept)        7.296
h(4-wind)          1.263
h(-2-dpg)         -0.052
h(174-ibt)        -0.043
h(doy-45)          0.097

Selected 5 of 18 terms, and 4 of 9 predictors (pmethod="seqrep")
Termination condition: Reached nk 21
Importance: ibt, doy, humidity-unused, wind, dpg, vh-unused, temp-unused, ...
Number of terms at each degree of interaction: 1 4 (additive model)
GCV 4.02    RSS 122    GRSq 0.413    RSq 0.628
> tab <- data.frame(pmethod=c("none", "backward", "forward", "exhaustive", "seqrep"),
+                   grsq=c(mod.none$grsq,
+                          mod.backward$grsq,
+                          mod.forward$grsq,
+                          mod.exhaustive$grsq,
+                          mod.seqrep$grsq),
+                   nterms=c(length(mod.none$selected.terms),
+                            length(mod.backward$selected.terms),
+                            length(mod.forward$selected.terms),
+                            length(mod.exhaustive$selected.terms),
+                            length(mod.seqrep$selected.terms)))
> cat("\n")

> print(tab)
     pmethod   grsq nterms
1       none -4.110     18
2   backward  0.530      7
3    forward  0.412      4
4 exhaustive  0.530      7
5     seqrep  0.413      5
> 
> # check fix for bug reported by Meleksen Akin (Feb 2019, fixed in earth 5.0.0)
> # to fix this I added xlevels to earth objects
> lm.Species <- lm(Sepal.Length~Species, data=iris)
> predict.lm <- predict(lm.Species, newdata=data.frame(Species="setosa")) # ok
> earth.Species <- earth(Sepal.Length~Species, data=iris)
> predict.earth <- predict(earth.Species, newdata=data.frame(Species="setosa")) # used to fail
> print(predict.earth - predict.lm)
     Sepal.Length
[1,]    -8.88e-16
> stopifnot(max(abs(predict.lm - predict.earth)) < 1e-15)
> 
> # Check fix for bug reported by Max Kuhn (Oct 2020, fixed in earth 5.3.0):
> # Occasionally we used to put a 1 when we should have put a 2 into the dirs matrix.
> options.old <- options()
> options(width=1000)
> 
> library(modeldata)
> data(ames)
> vars <- c("Sale_Price", "Gr_Liv_Area", "Alley", "Mas_Vnr_Type", "BsmtFin_Type_2", "Condition_2")
> ames2 <- ames[,vars,drop=FALSE]
> ames2$Sale_Price <- log10(ames2$Sale_Price)
> # change colnames to something easier to work with
> colnames(ames2) <- c("Sale_Price", "g", "a", "m", "b", "c")
> ames2 <- as.data.frame(ames2)
> ames2.mod <- earth(Sale_Price ~ ., data = ames2, degree = 2,
+                    trace=4, pmethod="none")
Call: earth(formula=Sale_Price~., data=ames2, pmethod="none", trace=4, degree=2)

x[2930,20]:
        g aNo_Alley_Access aPaved mBrkFace mCBlock mNone mStone bBLQ bGLQ ...
1    1656                1      0        0       0     0      1    0    0 ...
2     896                1      0        0       0     1      0    0    0 ...
3    1329                1      0        1       0     0      0    0    0 ...
...  2110                1      0        0       0     1      0    0    0 ...
2930 2000                1      0        1       0     0      0    0    0 ...

y[2930,1]:
     Sale_Price
1          5.33
2          5.02
3          5.24
...        5.39
2930       5.27

Forward pass: minspan 8 endspan 11   x[2930,20] 458 kB   bx[2930,41] 939 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.5117 0.5134       0.5134    1            g        1822  2   3         1 
4      0.5575 0.5598      0.04638    6        mNone           0< 4             1 
6      0.5769 0.5798         0.02   11 bNo_Basement           0< 5             1 
8      0.5859 0.5894     0.009625    2 aNo_Alley_Ac           0< 6         4   2 
10     0.5946 0.5988     0.009388    7       mStone           0< 7             1 
12     0.6031 0.6079     0.009102    1            g        3390  8             1 
14     0.6103 0.6163     0.008397    1            g         954  9   10    4   2 
16     0.6159 0.6231      0.00684    1            g        2295  11  12   10   2 
18     0.6211 0.6289     0.005752    3       aPaved           0< 13        4   2 
20     0.6232 0.6316     0.002692    7       mStone           0< 14       12   2 
22     0.6250 0.6339     0.002325    4     mBrkFace           0< 15            1 
24     0.6261 0.6356     0.001703   15        cNorm           0< 16        4   2 
26     0.6274 0.6376     0.001973   16        cPosA           0< 17            1 
28     0.6282 0.6390     0.001401    9         bGLQ           0< 18            1 
30     0.6286 0.6400     0.001017    5      mCBlock           0< 19        3   2 
32     0.6290 0.6409    0.0009439   13         bUnf           0< 20       10   2 reject (small DeltaRSq)

RSq changed by less than 0.001 at 31 terms, 19 terms used (DeltaRSq 0.00094)
After forward pass GRSq 0.629 RSq 0.641
Forward pass complete: 31 terms, 19 terms used

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2      0.4817  0.4825     0.4817      1  1 3
          3      0.5117  0.5134     0.0301      1  1 2 3
          4      0.5575  0.5598     0.0458      2  1 2 3 4
          5      0.5769  0.5798     0.0194      3  1 2 3 4 5
          6      0.5880  0.5915     0.0112      4  1 2 3 5 7 15
          7      0.6019  0.6060     0.0139      4  1 2 3 5 7 14 15
          8      0.6108  0.6154     0.0089      6  1 2 3 5 6 7 14 15
          9      0.6157  0.6209     0.0049      6  1 2 3 5 6 7 10 14 15
         10      0.6197  0.6256     0.0041      6  1 2 3 5 6 7 9 10 14 15
         11      0.6245  0.6309     0.0048      7  1 2 3 5 6 7 9 10 13 14 15
         12      0.6243  0.6313    -0.0002      7  1 2 3 4 5 6 7 9 10 13 14 15
         13      0.6254  0.6331     0.0011      8  1 2 3 4 5 6 7 9 10 13 14 15 16
         14      0.6269  0.6351     0.0015      9  1 2 3 4 5 6 7 9 10 13 14 15 16 17
         15      0.6279  0.6367     0.0010      9  1 2 3 4 5 6 7 9 10 12 13 14 15 16 17
         16      0.6287  0.6381     0.0008     10  1 2 3 4 5 6 7 9 10 12 13 14 15 16 17 18
         17      0.6291  0.6391     0.0004     11  1 2 3 4 5 6 7 9 10 12 13 14 15 16 17 18 19
         18      0.6293  0.6400     0.0002     11  1 2 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19
chosen   19      0.6286  0.6400    -0.0006     11  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Prune none penalty 3 nprune null: selected 19 of 19 terms, and 11 of 20 preds
After pruning pass GRSq 0.629 RSq 0.64
> cat("\nsummary(ames2.mod)\n")

summary(ames2.mod)
> print(summary(ames2.mod))
Call: earth(formula=Sale_Price~., data=ames2, pmethod="none", trace=4, degree=2)

                         coefficients
(Intercept)                     5.275
mBrkFace                        0.082
mNone                          -0.152
mStone                          0.207
bGLQ                            0.062
bNo_Basement                   -0.151
cPosA                           0.216
h(1822-g)                       0.000
h(g-1822)                       0.000
h(g-3390)                       0.000
aNo_Alley_Access * mNone        0.112
aPaved * mNone                  0.119
mNone * cNorm                   0.096
h(1822-g) * mCBlock            -0.001
h(954-g) * mNone                0.000
h(g-954) * mNone                0.000
h(2295-g) * mStone              0.000
h(g-2295) * mStone              0.000
h(g-3390) * mStone             -0.001

Selected 19 of 19 terms, and 11 of 20 predictors (pmethod="none")
Termination condition: RSq changed by less than 0.001 at 19 terms
Importance: g, bNo_Basement, mNone, mBrkFace, mStone, aNo_Alley_Access, aPaved, cNorm, cPosA, bGLQ, mCBlock, bBLQ-unused, bLwQ-unused, bRec-unused, bUnf-unused, cFeedr-unused, cPosN-unused, cRRAe-unused, cRRAn-unused, cRRNn-unused
Number of terms at each degree of interaction: 1 9 9
GCV 0.0116    RSS 33    GRSq 0.629    RSq 0.64
> cat("\names2.mod$dirs\n")

ames2.mod$dirs
> print(ames2.mod$dirs)
                        g aNo_Alley_Access aPaved mBrkFace mCBlock mNone mStone bBLQ bGLQ bLwQ bNo_Basement bRec bUnf cFeedr cNorm cPosA cPosN cRRAe cRRAn cRRNn
(Intercept)             0                0      0        0       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-1822)               1                0      0        0       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(1822-g)              -1                0      0        0       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
mNone                   0                0      0        0       0     2      0    0    0    0            0    0    0      0     0     0     0     0     0     0
bNo_Basement            0                0      0        0       0     0      0    0    0    0            2    0    0      0     0     0     0     0     0     0
aNo_Alley_Access*mNone  0                2      0        0       0     2      0    0    0    0            0    0    0      0     0     0     0     0     0     0
mStone                  0                0      0        0       0     0      2    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-3390)               1                0      0        0       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-954)*mNone          1                0      0        0       0     2      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(954-g)*mNone         -1                0      0        0       0     2      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-2295)*mStone        1                0      0        0       0     0      2    0    0    0            0    0    0      0     0     0     0     0     0     0
h(2295-g)*mStone       -1                0      0        0       0     0      2    0    0    0            0    0    0      0     0     0     0     0     0     0
aPaved*mNone            0                0      2        0       0     2      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-3390)*mStone        1                0      0        0       0     0      2    0    0    0            0    0    0      0     0     0     0     0     0     0
mBrkFace                0                0      0        2       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
mNone*cNorm             0                0      0        0       0     2      0    0    0    0            0    0    0      0     2     0     0     0     0     0
cPosA                   0                0      0        0       0     0      0    0    0    0            0    0    0      0     0     2     0     0     0     0
bGLQ                    0                0      0        0       0     0      0    0    2    0            0    0    0      0     0     0     0     0     0     0
h(1822-g)*mCBlock      -1                0      0        0       2     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
> plotmo(ames2.mod, SHOWCALL=TRUE)
 plotmo grid:    g               a    m   b    c
              1442 No_Alley_Access None Unf Norm
> # check that there are no 1s in dirs, except for the "g" variable
> # all entries should be 0 or 2, because all vars are indicators (binary), so no knots
> stopifnot(all(ames2.mod$dirs[,-1,drop=FALSE] != 1)) # -1 drops "g" column
> stopifnot(ames2.mod$dirs["h(g-3390)*mStone",  "mStone"] == 2)
> 
> # same as above but with Auto.linpreds=FALSE
> ames2.mod.Auto.linpreds.FALSE <- earth(Sale_Price ~ ., data = ames2, degree = 2,
+                                        pmethod="none", Auto.linpreds=FALSE)
> cat("\nsummary(ames2.mod.Auto.linpreds.FALSE)\n")

summary(ames2.mod.Auto.linpreds.FALSE)
> print(summary(ames2.mod.Auto.linpreds.FALSE))
Call: earth(formula=Sale_Price~., data=ames2, pmethod="none", degree=2, Auto.linpreds=FALSE)

                         coefficients
(Intercept)                     5.275
h(1822-g)                       0.000
h(g-1822)                       0.000
h(g-3390)                       0.000
mBrkFace                        0.082
mNone                          -0.152
mStone                          0.207
bGLQ                            0.062
bNo_Basement                   -0.151
cPosA                           0.216
h(1822-g) * mCBlock            -0.001
h(954-g) * mNone                0.000
h(g-954) * mNone                0.000
h(2295-g) * mStone              0.000
h(g-2295) * mStone              0.000
h(g-3390) * mStone             -0.001
aNo_Alley_Access * mNone        0.112
aPaved * mNone                  0.119
mNone * cNorm                   0.096

Selected 19 of 19 terms, and 11 of 20 predictors (pmethod="none")
Termination condition: RSq changed by less than 0.001 at 19 terms
Importance: g, bNo_Basement, mNone, mBrkFace, mStone, aNo_Alley_Access, aPaved, cNorm, cPosA, bGLQ, mCBlock, bBLQ-unused, bLwQ-unused, bRec-unused, bUnf-unused, cFeedr-unused, cPosN-unused, cRRAe-unused, cRRAn-unused, cRRNn-unused
Number of terms at each degree of interaction: 1 9 9
GCV 0.0116    RSS 33    GRSq 0.629    RSq 0.64
> cat("\nAuto.linpreds.FALSE$dirs\n")

Auto.linpreds.FALSE$dirs
> print(ames2.mod.Auto.linpreds.FALSE$dirs)
                        g aNo_Alley_Access aPaved mBrkFace mCBlock mNone mStone bBLQ bGLQ bLwQ bNo_Basement bRec bUnf cFeedr cNorm cPosA cPosN cRRAe cRRAn cRRNn
(Intercept)             0                0      0        0       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-1822)               1                0      0        0       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(1822-g)              -1                0      0        0       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
mNone                   0                0      0        0       0     1      0    0    0    0            0    0    0      0     0     0     0     0     0     0
bNo_Basement            0                0      0        0       0     0      0    0    0    0            1    0    0      0     0     0     0     0     0     0
aNo_Alley_Access*mNone  0                1      0        0       0     1      0    0    0    0            0    0    0      0     0     0     0     0     0     0
mStone                  0                0      0        0       0     0      1    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-3390)               1                0      0        0       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-954)*mNone          1                0      0        0       0     1      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(954-g)*mNone         -1                0      0        0       0     1      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-2295)*mStone        1                0      0        0       0     0      1    0    0    0            0    0    0      0     0     0     0     0     0     0
h(2295-g)*mStone       -1                0      0        0       0     0      1    0    0    0            0    0    0      0     0     0     0     0     0     0
aPaved*mNone            0                0      1        0       0     1      0    0    0    0            0    0    0      0     0     0     0     0     0     0
h(g-3390)*mStone        1                0      0        0       0     0      1    0    0    0            0    0    0      0     0     0     0     0     0     0
mBrkFace                0                0      0        1       0     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
mNone*cNorm             0                0      0        0       0     1      0    0    0    0            0    0    0      0     1     0     0     0     0     0
cPosA                   0                0      0        0       0     0      0    0    0    0            0    0    0      0     0     1     0     0     0     0
bGLQ                    0                0      0        0       0     0      0    0    1    0            0    0    0      0     0     0     0     0     0     0
h(1822-g)*mCBlock      -1                0      0        0       1     0      0    0    0    0            0    0    0      0     0     0     0     0     0     0
> # check that there are no 2s in dirs with Auto.linpreds=FALSE
> stopifnot(all(ames2.mod.Auto.linpreds.FALSE$dirs != 2))
> stopifnot(abs(ames2.mod$rsq - ames2.mod.Auto.linpreds.FALSE$rsq) < 1e-10)
> 
> # Oct 2021 (earth 5.3.2): issue an error if x colnames are duplicated because of factor expansion.
> iris.dup <- transform(iris, Species=factor(as.numeric(Species) + 20),
+                             Species2=factor(as.numeric(Species)))
> # TODO $$ Mar 2022: We no longer get the expected error below,
> #                   but get it if we manually call try(earth(Sepal.Length ~ ., data=iris.dup))
> # expect.err(try(earth(Sepal.Length ~ ., data=iris.dup)),
> #            "Duplicate colname in x (colnames are \"Sepal.Width\", \"Petal.Length\", \"Petal.Width\", \"Species22\", \"Species23\", \"Species22\", \"Species23\")")
> # expect.err(try(earth(iris.dup[,-1], iris.dup[,1])),
> #            "Duplicate colname in x (colnames are \"Sepal.Width\", \"Petal.Length\", \"Petal.Width\", \"Species22\", \"Species23\", \"Species22\", \"Species23\")")
> 
> # check that lm has the same problem (but doesn't report it)
> lm.dup <- lm(Sepal.Length ~ ., data=iris.dup)
> stopifnot(identical(names(coef(lm.dup)),
+                     c("(Intercept)", "Sepal.Width", "Petal.Length", "Petal.Width",
+                       "Species22", "Species23", "Species22", "Species23")))
> 
> cat("--- test style=\"bf\" with various predictors ---------------------\n")
--- test style="bf" with various predictors ---------------------
> 
> data(etitanic)
> mod.bf1 <- earth(sex ~ pclass, data=etitanic, degree=2, trace=0)
> printh(summary(mod.bf1))
===summary(mod.bf1) 
Call: earth(formula=sex~pclass, data=etitanic, trace=0, degree=2)

            coefficients
(Intercept)        0.567
pclass3rd          0.130

Selected 2 of 3 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: pclass3rd, pclass2nd-unused
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0.231    RSS 240    GRSq 0.0133    RSq 0.018
> printh(summary(mod.bf1, style="bf"))
===summary(mod.bf1, style = "bf") 
Call: earth(formula=sex~pclass, data=etitanic, trace=0, degree=2)

male =
  0.567
  + 0.13 * bf1

   bf1  pclass3rd

Selected 2 of 3 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: pclass3rd, pclass2nd-unused
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0.231    RSS 240    GRSq 0.0133    RSq 0.018
> 
> etit.slash <- etitanic
> 
> etit.slash$`pclass/slash` = etit.slash$pclass
> etit.slash$pclass <- NULL
> 
> etit.slash$`survived/slash` = etit.slash$survived
> etit.slash$survived <- NULL
> 
> etit.slash$`age/slash` = etit.slash$age
> etit.slash$age <- NULL
> 
> mod.bf2 <- earth(sex ~ `pclass/slash`, data=etit.slash, degree=2, trace=0)
> printh(summary(mod.bf2))
===summary(mod.bf2) 
Call: earth(formula=sex~`pclass/slash`, data=etit.slash, trace=0, degree=2)

                coefficients
(Intercept)            0.567
pclass/slash3rd        0.130

Selected 2 of 3 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: `pclass/slash`3rd, `pclass/slash`2nd-unused
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0.231    RSS 240    GRSq 0.0133    RSq 0.018
> printh(summary(mod.bf2, style="bf"))
===summary(mod.bf2, style = "bf") 
Call: earth(formula=sex~`pclass/slash`, data=etit.slash, trace=0, degree=2)

male =
  0.567
  + 0.13 * bf1

   bf1  `pclass/slash`3rd

Selected 2 of 3 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 3 terms
Importance: `pclass/slash`3rd, `pclass/slash`2nd-unused
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 0.231    RSS 240    GRSq 0.0133    RSq 0.018
> 
> mod.bf3 <- earth(sex ~ ., data=etit.slash, degree=2, trace=0)
> printh(summary(mod.bf3))
===summary(mod.bf3) 
Call: earth(formula=sex~., data=etit.slash, trace=0, degree=2)

                                   coefficients
(Intercept)                              0.7868
pclass/slash3rd                         -0.5470
pclass/slash2nd * survived/slash        -0.1639
pclass/slash3rd * survived/slash         0.2100
h(4-parch) * pclass/slash3rd             0.1183
survived/slash * h(age/slash-15)         0.1722
survived/slash * h(age/slash-11.5)      -0.1725
h(2-sibsp) * h(4-parch)                  0.0243
h(sibsp-2) * h(4-parch)                  0.0651
h(4-parch) * h(25-age/slash)            -0.0045

Selected 10 of 15 terms, and 6 of 6 predictors
Termination condition: Reached nk 21
Importance: `survived/slash`, parch, `age/slash`, `pclass/slash`3rd, sibsp, `pclass/slash`2nd
Number of terms at each degree of interaction: 1 1 8
GCV 0.151    RSS 151    GRSq 0.352    RSq 0.38
> printh(summary(mod.bf3, style="bf"))
===summary(mod.bf3, style = "bf") 
Call: earth(formula=sex~., data=etit.slash, trace=0, degree=2)

male =
  0.787
  -   0.547 * bf1
  -   0.164 * bf2 * bf3
  +    0.21 * bf1 * bf3
  +   0.118 * bf4 * bf1
  +   0.172 * bf3 * bf5
  -   0.172 * bf3 * bf6
  +  0.0243 * bf7 * bf4
  +  0.0651 * bf8 * bf4
  - 0.00454 * bf4 * bf9

   bf1  `pclass/slash`3rd
   bf2  `pclass/slash`2nd
   bf3  `survived/slash`
   bf4  h(4-parch)
   bf5  h(`age/slash`-15)
   bf6  h(`age/slash`-11.5)
   bf7  h(2-sibsp)
   bf8  h(sibsp-2)
   bf9  h(25-`age/slash`)

Selected 10 of 15 terms, and 6 of 6 predictors
Termination condition: Reached nk 21
Importance: `survived/slash`, parch, `age/slash`, `pclass/slash`3rd, sibsp, `pclass/slash`2nd
Number of terms at each degree of interaction: 1 1 8
GCV 0.151    RSS 151    GRSq 0.352    RSq 0.38
> 
> options(options.old) # no more width=1000
> 
> source("test.epilog.R")
