CLINSTANDARDS.ORG Mini Deep Dive
What the SAS Viya 2026.03 Base SAS Procedures Guide Tells Us
With the SAS Viya 2026.03 release (April 2026), SAS Institute introduced PROC R as an official procedure listed in the Base SAS Procedures Guide. This is not a third-party macro, not an IML workaround, and not a community hack. PROC R is a SAS-supported procedure for running R code within the SAS environment, paralleling PROC PYTHON in both design and capability.
For the clinical statistical programming community, this is a notable development. Since 2008, the only official pathway from SAS to R was through PROC IML, which required the separately licensed SAS/IML module. The community-developed %PROC_R macro offered a Base SAS alternative, but it was unsupported and limited. PROC R's placement in the Base SAS Procedures Guide suggests a more accessible pathway, though the exact licensing and configuration requirements should be confirmed with SAS documentation or your SAS administrator.
| What We Know from the Documentation | PROC R appears in the Base SAS Procedures Guide for SAS Viya (v2026.03, dated April 2026). It follows the same submit/endsubmit pattern as PROC PYTHON. The documentation describes data transfer between SAS datasets and R data frames, macro variable exchange, SAS function access from R, and R graphics rendering in SAS Studio. What remains to be confirmed: exact licensing terms, R version requirements, and whether additional R packages beyond those referenced in the documentation are available. |
According to the SAS documentation, the R procedure enables the following capabilities within a SAS session:
| Capability | Clinical Programming Impact |
| Run R code within SAS | Execute R scripts for statistical analysis, data manipulation, and visualization without leaving the SAS environment |
| Move data between SAS datasets and R data frames | Transfer ADaM/SDTM datasets to R for analysis and bring results back to SAS for reporting |
| Transfer SAS macro variables to/from R variables | Pass study-level parameters (STUDYID, CUTOFF dates, analysis flags) between environments dynamically |
| Call SAS functions within R code | Leverage SAS functions (PUT, INPUT, date/time functions) from within R scripts for format-aware processing |
| Submit SAS code from R | Trigger SAS procedures (PROC SORT, PROC MEANS) from within an R workflow for hybrid pipelines |
| Display R graphics in SAS Studio | Render ggplot2, survminer, and Base R graphics directly in SAS Studio results, including KM plots, forest plots, and waterfall charts |
| Run R in batch mode | Execute R-based production pipelines in validated batch environments for regulatory deliverables |
The PROC R documentation references the following R packages. The exact nature of this association (pre-installed, recommended, or listed as dependencies) should be confirmed with the full SAS documentation for your deployment:
| Package | Purpose | Clinical Relevance |
| R6 | Object-oriented R programming framework | Encapsulated analysis objects |
| arrow | High-performance columnar data exchange (Apache Arrow) | Fast SAS-to-R data transfer; Dataset-JSON support |
| haven | Read/write SAS (XPT, SAS7BDAT), SPSS, Stata files | Essential for CDISC XPT file I/O |
| plotly | Interactive web-based visualizations | Interactive safety and efficacy dashboards |
| svglite | Lightweight SVG graphics output | High-quality vector graphics for TFLs |
proc r;
submit;
# All R code goes between submit and endsubmit
library(dplyr)
# Pull SAS data into R
adsl <- sas.sd2df("ADAM.ADSL")
# R analysis
trt_summary <- adsl %>%
group_by(TRT01A) %>%
summarise(N = n(), Mean_Age = mean(AGE))
# Push results to SAS
sas.df2sd(trt_summary, "WORK.TRT_SUMMARY")
endsubmit;
run;
/* SAS continues with the result */
proc print data=work.trt_summary noobs; run;
One of the most compelling use cases for PROC R is generating publication-quality survival curves using R's {survival} and {survminer} packages, which produce output that exceeds SAS's native ODS Graphics capabilities.
proc r;
submit;
library(survival)
library(survminer)
adtte <- sas.sd2df("ADAM.ADTTE")
fit <- survfit(Surv(AVAL, CNSR==0) ~ TRT01A, data = adtte)
ggsurvplot(fit,
data = adtte,
risk.table = TRUE,
pval = TRUE,
palette = c("#2E86C1", "#E74C3C"),
xlab = "Time (Months)",
ylab = "Survival Probability",
title = "Overall Survival by Treatment Arm",
legend.labs = c("Placebo", "Active Treatment"),
risk.table.height = 0.25,
ggtheme = theme_minimal())
endsubmit;
run;
proc r;
submit;
library(ggplot2)
subgroups <- data.frame(
Subgroup = c("Overall", "Age < 65", "Age >= 65",
"Male", "Female", "ECOG 0", "ECOG 1"),
HR = c(0.72, 0.68, 0.78, 0.70, 0.75, 0.65, 0.82),
LCL = c(0.58, 0.49, 0.59, 0.52, 0.55, 0.45, 0.62),
UCL = c(0.89, 0.94, 1.03, 0.94, 1.02, 0.94, 1.08),
N = c(500, 280, 220, 260, 240, 190, 310))
ggplot(subgroups, aes(x=HR, y=reorder(Subgroup, -HR))) +
geom_point(size=3, color='#1B4F72') +
geom_errorbarh(aes(xmin=LCL, xmax=UCL), height=0.2,
color='#2E86C1') +
geom_vline(xintercept=1, linetype="dashed", color="grey40") +
labs(x="Hazard Ratio (95% CI)", y="",
title="Forest Plot: OS by Subgroup") +
theme_minimal(base_size=13)
endsubmit;
run;
proc r;
submit;
library(ggplot2)
adrs <- sas.sd2df("ADAM.ADRS")
adrs <- adrs[adrs$PARAMCD == "OVRLRESP",]
adrs <- adrs[order(adrs$PCHG),]
adrs$SUBJORD <- seq_len(nrow(adrs))
ggplot(adrs, aes(x=SUBJORD, y=PCHG, fill=AVALC)) +
geom_bar(stat='identity') +
geom_hline(yintercept=c(-30, 20),
linetype="dashed", color="grey50") +
scale_fill_manual(values=c("CR"="#1E8449",
"PR"="#2ECC71", "SD"="#F39C12", "PD"="#E74C3C")) +
labs(x="Subject", y="Best % Change from Baseline",
title="Waterfall Plot: Best Overall Response",
fill="Response") +
theme_minimal()
endsubmit;
run;
| Feature | PROC R (2026+) | PROC IML + R | %PROC_R Macro |
| License Required | Listed in Base SAS Proc Guide (Viya); confirm with SAS admin | SAS/IML (paid add-on) | Base SAS only |
| SAS Support | Official SAS procedure | Official (via IML) | Community/unsupported |
| Syntax | proc r; submit; endsubmit; | proc iml; submit / R; endsubmit; | %PROC_R() macro call |
| Data Transfer | Built-in methods | ExportDataSetToR / ImportDataSetFromR | CSV-based file I/O |
| R Graphics in SAS | Native SAS Studio display | Local only; not on remote servers | File output only |
| Macro Variable Access | Direct transfer | Not supported directly | Not supported |
| Referenced R Packages | R6, arrow, haven, plotly, svglite (confirm availability) | None (user installs) | None |
| Batch Mode | Supported | Supported | Limited |
| SAS Platform | SAS Viya | SAS 9.4 / Viya | SAS 9.4 |
With PROC R joining PROC PYTHON, SAS now offers a symmetric integration architecture. Both procedures follow the same design pattern, making it easy for programmers to work in either open-source language from within SAS.
| Aspect | PROC R | PROC PYTHON |
| Invocation | proc r; submit; ... endsubmit; run; | proc python; submit; ... endsubmit; run; |
| SAS Data → Open-Source | sas.sd2df("LIB.DS") | SAS.sd2df("LIB.DS") |
| Open-Source → SAS Data | sas.df2sd(df, "LIB.DS") | SAS.df2sd(df, "LIB.DS") |
| Get Macro Variable | sas.symget("VAR") | SAS.symget("VAR") |
| Set Macro Variable | sas.symput("VAR", val) | SAS.symput("VAR", val) |
| Submit SAS Code | sas.submit("SAS code") | SAS.submit("SAS code") |
| Clinical Strength | Stats, visualizations, {pharmaverse} | Automation, ML, NLP |
/* Check if PROC R is available */
proc r;
submit;
R.version.string
.libPaths()
installed.packages()[, c('Package', 'Version')]
endsubmit;
run;
Before using PROC R for production deliverables, start with a QC workflow. Use PROC R to independently verify SAS-generated summary statistics.
/* SAS primary output */
proc means data=adam.adsl n mean std;
class TRT01A;
var AGE BMIBL WEIGHTBL;
output out=work.sas_stats;
run;
/* R-based independent QC via PROC R */
proc r;
submit;
adsl <- sas.sd2df("ADAM.ADSL")
r_stats <- adsl %>%
group_by(TRT01A) %>%
summarise(across(c(AGE, BMIBL, WEIGHTBL),
list(N=~sum(!is.na(.)), Mean=~mean(.,na.rm=T),
SD=~sd(.,na.rm=T))))
sas.df2sd(r_stats, "WORK.R_STATS")
endsubmit;
run;
/* Compare SAS vs R results */
proc compare base=work.sas_stats compare=work.r_stats;
run;
Once QC workflows are established, use PROC R for production-quality visualizations that complement SAS-generated TFLs. Focus on outputs where R demonstrably exceeds SAS capabilities: KM plots with integrated risk tables, forest plots, waterfall plots, and swimmer plots.
PROC R's appearance in the Base SAS Procedures Guide for SAS Viya is a significant step in SAS's open-source integration story. By listing R integration as a standalone procedure alongside PROC PYTHON, SAS has signaled its commitment to supporting multi-language workflows within the SAS environment.
For clinical programming teams on SAS Viya, the practical next steps are: verify PROC R availability in your deployment, confirm licensing terms with your SAS administrator, start with QC and visualization use cases, and gradually expand to hybrid workflows that leverage the strengths of both languages. The combination of SAS's validated data pipeline with R's statistical depth and visualization capabilities is a compelling proposition, and PROC R appears to make it more accessible than the PROC IML pathway that preceded it.
1. SAS Institute. R Procedure: Overview. Base SAS Procedures Guide, v2026.03. documentation.sas.com/doc/en/pgmsascdc/v_073/proc/p13zn8bv8gu2won1dvff9a2x9qb7.htm.
2. SAS Institute. R Procedure: Concepts. Base SAS Procedures Guide, v2026.03. documentation.sas.com.
3. SAS Institute. PROC PYTHON Documentation. Base SAS Procedures Guide. documentation.sas.com.
4. SAS Institute. SAS/IML Interface to R. SAS 9.4 Programming Documentation. documentation.sas.com.
5. SAS Developer Portal. R Resources. developer.sas.com/open-source/r.
clinstandards.org
Free, non-commercial education for the CDISC and statistical programming community
No comments yet. Be the first!