Base SAS statements\functions\procedures
with R analogs
Table of Contents:
Create sample data .......................................................................................................................................................................................2
Create a copy of an existing dataset ................................................................................................................................................................2
Subset observations ......................................................................................................................................................................................2
Subset variables ............................................................................................................................................................................................2
Subset observations and variables ..................................................................................................................................................................2
Renaming variables .......................................................................................................................................................................................3
Adding new variables .....................................................................................................................................................................................3
Appending datasets .......................................................................................................................................................................................3
Merging datasets ...........................................................................................................................................................................................3
Sorting ..........................................................................................................................................................................................................4
One-way frequence(record count) ..................................................................................................................................................................4
Descriptive statistics for numeric variables......................................................................................................................................................4
First Dot concept ...........................................................................................................................................................................................4
Last Dot concept ...........................................................................................................................................................................................5
First dot and Last dot .....................................................................................................................................................................................5
Remove duplicates ........................................................................................................................................................................................5
Transpose data ..............................................................................................................................................................................................6
Arrays ...........................................................................................................................................................................................................6
General Notes ...............................................................................................................................................................................................7
Title SAS R Comment
Create sample data class; class <- tribble(~Name, ~Sex, ~Age, ~Height, ~Weight,
data infile datalines dlm = ‘|’ dsd missover; “Alfred”, “M”, 14, 69, 112.5,
input Name: $8. Sex: $1. Age: best32. Height: “Alice”, “F”, 13, 56.5, 84,
best32. Weight: best32.; “Barbara”, “F”, 13, 65.3, 98)
datalines;
Alfred|M|14|69|112.5
Alice|F|13|56.5|84
Barbara|F|13|65.3|98;
run;
Create a copy of data new_class; new_class <- class
an existing set class;
dataset run;
Subset data males; males <- filter(class, Sex==”M”)
observations set class;
where sex=”M”;
run;
data preteen; preteen <- filter(class, Age %in% c(11,12))
set class;
where age in (11, 12);
run;
Subset variables data subset; subset <- select(class, Name, Sex, Age)
set class;
keep Name Sex Age;
run;
data subset; subset <- select(class, -Height, -Weight) Minus before the variables
set class; means drop
drop height weight;
run;
data subset; subset <- select(class, -starts_with(c(“H”, “W”)))
set class; subset <- select(class, -ends_with(“t”))
drop h: w:;
run;
Subset data males; males <- class %>% %>% - Means created data
observations and set class; filter(Sex==”M”) %>% frame is moved to the next
variables where sex=”M”; select(-Sex) record to be used in there.
drop sex;
run;
Renaming data renamed; renamed <- rename(class, Age_years = Age, Height_in = Height)
variables set class;
rename age=age_years height = height_in;
run;
data renamed;
set class (rename = (age=age_years height =
height_in));
run;
Adding new data dm01; dm01 <- mutate(dm, Agemon = 12*Age, Group = 1)
variables set dm;
Agemon = age*12;
Group = 1;
run;
data dm01; dm01 <- mutate(dm, Agegr1 = case_when(
set dm; Age >=60 ~ “>= 60 Years”,
length agegr1 $30; between(Age, 20, 59) ~ “20 - < 60 Years,
if age < 20 then agegr1 = “<20 Years”; Age < 20 ~ “< 20 Years”))
else If 20 <= age < 60 then agegr1 = “20 - <60
Years”;
else If age >= 60 then agegr1 = “>= 60 Years”;
run;
Appending data class; class <- bind_rows(males, females)
datasets set males females;
run;
Merging datasets data full; full <- full_join(Sex, ahw, by = “Name”)
merge sex (in = a) ahw (in = b);
by Name;
run;
data full; full <- left_join(Sex, ahw, by = “Name”)
merge sex (in = a) ahw (in = b);
by Name;
if a;
run;
data full; full <- right_join(Sex, ahw, by = “Name”)
merge sex (in = a) ahw (in = b);
by Name;
if b;
run;
data full; full <- inner_join(Sex, ahw, by = “Name”)
merge sex (in = a) ahw (in = b);
by Name;
if a and b;
run;
data full; full <- anti_join(Sex, ahw, by = c(“Name”)) anti_join checks that record
merge sex (in = a) ahw (in = b); is present in the data frame
by Name; from 1st parameter and not
if a and not b; present in the data frame
run; which is mentioned as the 2nd
parameter
proc sql; dummy01 <- cross_join(dummy, dummy_treatments) Merging without by group -
create table dummy01 as all-to-all. As example – merge
select * all the possible treatments
from dummy, dummy_treatments; (from dummy_treatments) to
quit; each record from dummy
dataset. Multiple records will
be created as the result
Sorting proc sort data = class out = sorted; sorted <- arrange(class, Age, desc(Height))
by age descending height;
run;
One-way proc freq data = class; counts01 <- count(class, Sex)
frequence(record tables sex/out = counts01;
count) run;
proc freq data = class; counts01 <- count(class, Sex, Age)
tables sex*age/out = counts01;
run;
Descriptive proc summary data = class; stats01 <- summarize(class, n = n( ), mean = mean(Height), sd = n( ) – doesn’t contain any
statistics for var height; sd(Height)) parameters to be set and
numeric output out = stats01 n = n mean = mean std = sd; returns number of records in
variables run; selected group
proc summary data = class; stats01 <- class %>%
class sex; group_by(Sex) %>%
var height; summarize(n = n( ), mean = mean(Height), sd = sd(Height))
output out = stats01 n = n mean = mean std = sd;
run;
First Dot concept proc sort data = class; counter <- class %>% row_number() – returns
by sex height weight name; arrange(Sex, Height, Weight, Name) %>% incremented value for each
run; group_by(Sex) %>% new record by selected group
mutate(counter = row_number())
data counter;
set class;
by sex height weight name;
if [Link] then counter = 1;
else counter + 1;
run;
proc sort data = class; lowestheight <- class %>% slice takes just a record
by sex height; arrange(Sex, Height) %>% which is mentioned in
run; group_by(Sex) %>% brackets based on sorting
slice(1) %>% order and grouping which are
data lowestheight; select(Name, Sex, Height) performed above
set class;
by sex height;
if [Link];
keep sex height name;
run;
Last Dot concept proc sort data = class; highestheight <- class %>% n() returns a number of
by sex height; arrange(Sex, Height) %>% records within a group
run; group_by(Sex) %>% selected by Group_by
slice(n())%>% statement which means that
data highestheight; select(Name, Sex, Height) n() return number of last
set class; record
by sex height;
if [Link];
keep sex height name;
run;
First dot and Last proc sort data = class; only_one_in_group <- class %>%
dot by age; group_by(Age) %>%
run; mutate(nrows=n()) %>%
filter(nrows==1)
data only_one_in_group;
set class;
by age;
if [Link] and [Link];
run;
Remove proc sort data = ae; nodupkey <- ae %>%
duplicates by subjid term stdtc; arrange(subjid, term, stdtc) %>%
run; group_by(subjid, term) %>%
slice(1)
proc sort data = ae out = nodupkey nodupkey;
by subjid term;
run;
proc sort data = ae out = noduprec noduprec; noduprec <- ae %>% distinct() removes all dups
by _ALL_; distinct() across all the variables
run;
Transpose data proc sort data = long; by subjid; run; wide <- pivot_wider(long,
id_cols = subjid,
proc transpose data = long out = wide; values_from = lbstresn,
by subjid; names_from = lbtestcd)
var lbstresn;
id lbtestcd;
run;
proc sort data = wide; by subjid; run; long <- pivot_longer(wide,
cols = c(HGB, ALT, AST),
proc transpose data = wide out = long (rename = (col1 = values_to = “lbstresn”,
lbstresn)) name = lbtestcd; names_to = “lbtestcd”)
by subjid;
var HGB ALT AST;
run;
Arrays data class; class <- tribble(~Name, ~Sex, ~Age, ~Height, ~Weight, ~Date1,
Name = "Alfred"; Sex = "M"; Date01 = "27/JAN/2023"; ~Date2,
Date02 = "17/FEB/2023"; output; "Alfred", "M", 14, 69, 112.5,"27/JAN/2023","17/FEB/2023",
Name = "Alice"; Sex = "F"; Date01 = "13/AUG/2021"; "Alice", "F", 13, 56.5, 84,"13/AUG/2021","24/OCT/2021",
Date02 = "24/OCT/2021"; output; "Barbara", "F", 13, 60, 98,"02/JAN/2022","21/MAR/2022",
Name = "Barbara"; Sex = "F"; Date01 = "02/JAN/2022"; "Barbara", "F", 13, 60, 98,"07/MAR/2023","10/APR/2023")
Date02 = "21/MAR/2022"; output;
Name = "Barbara"; Sex = "F"; Date01 = "07/MAR/2023";
Date02 = "10/APR/2023"; output; class03 <- class %>%
run; mutate(across(c(Date1, Date2), ~ str_replace_all(., "/", "-")))
data class03;
set class;
array rvars{*} date01 date02;
do i = 1 to dim(rvars);
rvars[i] = translate(rvars[i],'-','/');
end;
run;
General Notes
• The source of these notes: [Link]
• All the names\parameters are case sensitive in R.
• Package tidyverse to be installed to use some of above statements\functions\procedures. To install:
[Link](“tidyverse”)
library(tidyverse)
• R studio is recommended to be installed.