---
title: "Getting started with ncvreg"
author: "Patrick Breheny"
output:
  rmarkdown::html_vignette:
    css: vignette.css
vignette: >
  %\VignetteIndexEntry{Getting started with ncvreg}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE}
library(ncvreg)
set.seed(4)
knitr::opts_knit$set(aliases=c(h = 'fig.height', w = 'fig.width'))
knitr::opts_chunk$set(
  comment = "#",
  collapse=TRUE,
  cache=FALSE,
  tidy=FALSE,
  dev.args = list(symbolfamily = 'CMU Sans Serif'))
knitr::knit_hooks$set(small.mar = function(before, options, envir) {
  if (before) par(mar = c(4, 4, .1, .1))
})
```

**[ncvreg](https://pbreheny.github.io/ncvreg/)** is an R package for fitting regularization paths for linear regression, GLM, and Cox regression models using lasso or nonconvex penalties, in particular the minimax concave penalty (MCP) and smoothly clipped absolute deviation (SCAD) penalty, with options for additional L<sub>2</sub> penalties (the "elastic net" idea).  Utilities for carrying out cross-validation as well as post-fitting visualization, summarization, inference, and prediction are also provided.

`ncvreg` comes with a few example data sets; we'll look at `Prostate`, which has 8 features and one continuous response, the PSA levels (on the log scale) from men about to undergo radical prostatectomy:

```{r prostate}
data(Prostate)
X <- Prostate$X
y <- Prostate$y
```

To fit a penalized regression model to this data:

```{r fit}
fit <- ncvreg(X, y)
```

The default penalty here is the minimax concave penalty (MCP), but SCAD and lasso penalties are also available.  This produces a path of coefficients, which we can plot with

```{r plot, h=4, w=6, small.mar=TRUE}
plot(fit)
```

Notice that variables enter the model one at a time, and that at any given value of $\lambda$, several coefficients are zero.  To see what the coefficients are, we could use the `coef` function:

```{r coef}
coef(fit, lambda=0.05)
```

The `summary` method can be used for post-selection inference:

```{r summary, output.lines=1:5}
summary(fit, lambda=0.05)
```

In this case, it would appear that `lcavol`, `svi`, and `lweight` are clearly associated with the response, even after adjusting for the other variables in the model, while `lbph`, `age`, and `pgg45` may be false positives included simply by chance.

Typically, one would carry out cross-validation for the purposes of assessing the predictive accuracy of the model at various values of $\lambda$:

```{r cvplot, h=5, w=6}
cvfit <- cv.ncvreg(X, y)
summary(cvfit)
plot(cvfit)
```

The value of $\lambda$ that minimizes the cross-validation error is given by `cvfit$lambda.min`, which in this case is `r round(cvfit$lambda.min,3)`.  Applying `coef` to the output of `cv.ncvreg` returns the coefficients at that value of $\lambda$:

```{r cvcoef}
coef(cvfit)
```

Predicted values can be obtained via `predict`, which has a number of options:

```{r predict}
predict(cvfit, X=head(X))     # Prediction of response for new observations
predict(cvfit, type="nvars")  # Number of nonzero coefficients
predict(cvfit, type="vars")   # Identity of the nonzero coefficients
```

Note that the original fit (to the full data set) is returned as `cvfit$fit`; it is not necessary to call both `ncvreg` and `cv.ncvreg` to analyze a data set.  For example, `plot(cvfit$fit)` will produce the same coefficient path plot as `plot(fit)` above.
