---
title: "sasLM for SAS Users"
author: "Kyun-Seop Bae"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{sasLM for SAS Users}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(comment = NA)
options(width = 100)
library(sasLM)
```

## Why sasLM?

Many statisticians move between SAS and R, and they expect the *same numbers* from both.
For unbalanced or complex designs, however, popular R functions often produce sums of squares,
standard errors, or least squares means that differ from those of SAS PROC GLM.
The differences are not necessarily errors - they come from different conventions
(types of sums of squares, coding of singular designs, denominators, quantile definitions, and so on).

`sasLM` implements the conventions of SAS so that the results match SAS PROC GLM, REG,
ANOVA, TTEST, FREQ (2x2 tables), and UNIVARIATE. The package is written in base R with
only `mvtnorm` as an additional dependency, and its results have been validated against
SAS outputs and the textbooks listed in `?sasLM`.

## Procedure-to-function map

| SAS                         | sasLM                                  |
|-----------------------------|----------------------------------------|
| PROC GLM                    | `GLM`, `aov1`, `aov2`, `aov3`, `EMS`   |
| PROC GLM SOLUTION           | `GLM(..., BETA=TRUE)`, `REG`           |
| PROC GLM LSMEANS            | `LSM`, `GLM(..., EMEAN=TRUE)`          |
| PROC GLM LSMEANS / PDIFF    | `PDIFF`, `Diffogram`                   |
| PROC GLM ESTIMATE/CONTRAST  | `est`, `ESTM`, `CIest`, `CONTR`        |
| PROC GLM RANDOM / TEST      | `RanTest`, `EMS`, `T3test`             |
| PROC GLM SLICE              | `SLICE`                                |
| PROC REG                    | `REG`, `lr`, `lr0`, `regD`, `Coll`     |
| PROC ANOVA                  | `aov1`                                 |
| PROC TTEST                  | `TTEST`, `tmtest`, `mtest`, `vtest`    |
| PROC UNIVARIATE             | `UNIV` and the descriptive functions   |
| PROC FREQ (2x2, stratified) | `RD`, `RR`, `OR`, `RDmn`, `RRmn`, `ORmn`, `ORcmh` |

## PROC GLM

The SAS code

```
PROC GLM DATA=np;
  CLASS block N P K;
  MODEL yield = block N*P*K / SOLUTION;
  LSMEANS N*P / CL;
RUN;
```

corresponds to:

```{r}
GLM(yield ~ block + N*P*K, npk)
```

`GLM` returns the overall ANOVA, fit statistics, and the Type I, II, and III tables
in one call. Note the agreement with SAS for this unbalanced design - this is the
core purpose of the package.

Coefficients as with the SOLUTION option:

```{r}
GLM(yield ~ block + N*P*K, npk, BETA=TRUE)$Parameter
```

Least squares means with confidence limits:

```{r}
LSM(weight ~ feed, chickwts, "feed")
```

Pairwise differences as with LSMEANS / PDIFF, including the Tukey adjustment:

```{r}
PDIFF(weight ~ feed, chickwts, "feed", adj="tukey")
```

The Dunnett test uses the first level as the control when `ref` is not given, as SAS does:

```{r}
PDIFF(weight ~ feed, chickwts, "feed", adj="dunnett")
```

## Expected mean squares and random effects

`EMS` produces the expected mean squares table, and `RanTest` performs the tests
with a random factor as the RANDOM / TEST statement of SAS PROC GLM:

```{r}
EMS(yield ~ block + N*P*K, npk)
RanTest(yield ~ block + N*P*K, npk, Random="block")
```

## PROC REG

```{r}
REG(mpg ~ wt + hp, mtcars)
```

Heteroscedasticity-consistent standard errors (HC0, HC3) and White's test:

```{r}
REG(mpg ~ wt, mtcars, HC=TRUE)
```

Weighted least squares follows the SAS WEIGHT statement: observations with
nonpositive weights are excluded, and `Resid=TRUE` returns fitted values and
residuals in the original scale as OUTPUT P= R= does.

```{r}
w = mtcars$cyl
head(REG(mpg ~ wt + hp, mtcars, Weights=w, Resid=TRUE)$Fitted)
```

## PROC TTEST

```{r}
TTEST(mtcars$mpg[mtcars$am==0], mtcars$mpg[mtcars$am==1])
```

With summarized input (mean, SD, n) only:

```{r}
tmtest(5.4, 2.2, 30, 4.8, 2.0, 28)
```

## PROC UNIVARIATE

```{r}
UNIV(mtcars$mpg)
```

The quartiles and the interquartile range use quantile type 2, the SAS default definition.

## 2x2 tables

Risk difference, relative risk, and odds ratio with score confidence intervals:

```{r}
RD(7, 10, 3, 10)
RR(7, 10, 3, 10)
OR(7, 10, 3, 10)
```

See the vignette *Stratified 2x2 Tables* for the stratified Miettinen-Nurminen
methods and meta-analysis.

## Notes

* All functions take a formula and a `data.frame`; factors follow the order of levels,
  which corresponds to the sorted CLASS levels of SAS.
* `GLM` is fast even for large data sets, since version 1.0.0.
* For the philosophy and validation materials, see the references in `?sasLM`.
