From one plan, Sapling writes each table program twice: in SAS, with the macro library of Sapling, and in R, with a twin library that has one function for each macro. The two read the same, block by block: the same calls, the same arguments, in the same order. Then Sapling compares every number.
The commands#
sapling build # the SAP, the specifications, the programs
sapling run # the ADaM data and the tables of the R engine
sapling sas programs # out/sas/programs/*.sas (no SAS needed)
sapling sas run # on a SAS server through DataStep Studio
sapling sas check # every number of R against the number of SAS: out/sas/check.md
sapling r programs # the readable R programs: out/r/programs/*.R
SAS runs through DataStep Studio, a separate product. Without SAS you get the plan, the specifications, the R programs and the dashboard of R.
A table in SAS and in R#
Table 14.1.1 of the made-up study SYNHTN01. The SAS program holds the population and the records in DATA steps, one call per block, then %stack, %columns, %ard (every number, from the results), %layout and %print:
%freq(
data = adsl
, var = ittfl
, by = trt01p
, levels = ittfl 'Y'
, total = yes
, label = "ITT population"
, out = t14_1_1_itt_summ
)
The R program calls the function of the same name with the same arguments:
t14_1_1_itt_summ <- freq(
data = adsl
, var = ittfl
, by = trt01p
, levels = list(ittfl = "Y")
, total = "yes"
, label = "ITT population"
)
A result has the same shape in both: the same columns, the same rows in the same order, the same text of the numbers. An error is the same message with its fix: line.
R against SAS#
The SAS macros share no code with the R engine, so two engines that agree are an independent check. On the made-up study SYNHTN01 the check reads SAS CHECK PASS: 759 of 759 numbers of R are the same in SAS. That is a made-up study; the figure says the programs agree, not that a trial worked. Differences that remain are named, with their size: a Cox model's hazard ratios and p-values from PROC PHREG with Efron ties differ from R in the seventh digit or later, and the page says so.
The macro library and its R twin#
The SAS macros are written in a house standard: readable programs, data in and data out, plain names (%describe, %freq, %stack, %print, %kmplot), and %print the only printer. The macro library and its manual are free to use; each macro carries a header that says what it does. The R twin has one function for each macro; where base R already has a function of the name, the twin is tlf_<name> (tlf_stack, tlf_print).