Hello, I am trying to run some R code from within SAS Enterprise Guide (7.13). I have a program that I am borrowing from Dr. Xin Wei, which I'll paste at the bottom of this post. Dr. Wei's JSTAT article (see: https://www.jstatsoft.org/article/view/v046c02) there has some great starter code, which I've been trying out. But they all result in PIPE errors. Here's an example: data test; do x=1 to 4; array a[4] a1-a4; do i=1 to 4; a[i] = rannor(100); end; output; end; drop i x; run; %include "e:\sasroot\Proc_R\Proc_R.sas"; %Proc_R (SAS2R = test, R2SAS =); cards4; R> testm <- as.matrix(test) R> eigen(testm) ;;;; %quit; --- ERROR: Insufficient authorization to access PIPE. ERROR: Error in the FILENAME statement. ERROR: No logical assign for filename PROC_R. I have seen solutions to PIPE errors (e.g., http://support.sas.com/kb/41/058.html) by changing the server properties to allow external commands (XCMD). But that poses a security threat in my workplace. So I would rather edit portions of the Proc_R.sas file (from https://www.jstatsoft.org/article/view/v046c02) that are trying to initiate external commands. Unfortunately I don't even know how to identify these these external command attempts. Can you help me find them? And maybe even suggest alternative code? That would be so wonderful. ***********************************************************************************************************************
***********A macro that execute R scipt in base SAS********************************************************************
** MACRO Version: 1.0 **
** SAS Version: 9.1.3/9.2 **
** R Version: 2.14.0 **
** Date: Nov 24, 2011 **
** Author: Xin Wei, Ph.D. **
** Affiliation: Roche Pharmaceuticals, INC **
** Instruction: This SAS macro enables native R language to be embedded in and executed along with a SAS program **
** in the Base SAS environment under Windows OS. This macro executes a user-defined R code in batch **
** mode by calling the unnamed pipe method within base SAS. The R textual and graphical output can be**
** routed to the SAS output window and result viewer, respectively. Also, this macro automatically **
** converts data between SAS datasets and R data frames such that the data and results from each **
** statistical environment can be utilized by the other environment. The objective of this macro is **
** to leverage the strength of the R programming language within the SAS environment in a systematic **
** manner. Moreover, this macro helps statistical programmers to learn a new statistical language **
** while staying in a familiar environment. The macro variables are described as follows: **
** SAS2R specifies the names of SAS datasets to be converted to R dataframe. Can be single file name or **
** multiple files whose names are separated by space. **
** R2SAS specifies the names of R dataframes to be converted to SAS datasets. Can be single file name or **
** multiple files whose names are separated by space. **
** rpath The full path and file names of R executable file for various R version from 2.11 to 2.14 **
***********************************************************************************************************************;
options nomerror nomprint nomlogic nosymbolgen;
options nonotes;
%macro proc_R(SAS2R=, R2SAS=);
options notes;
%GLOBAL _SAS2R _R2SAS saswork r_code;
%let _SAS2R=&SAS2R;
%let _R2SAS=&R2SAS;
%let saswork=%sysfunc(pathname(work));
data _null_;
call symput('r_code','r_code'||trim(left(scan(put(datetime(),best.),1,'.'))));
run;
%put &r_code;
data _null_;
file "&saswork\&r_code..r";
infile cards4;
input;
put _infile_;
%mend Proc_R;
%macro quit(rpath=%str(C:\Progra~1\R\R-3.3.2\bin\R.exe));
****for R-2.11.0, use: C:\Progra~1\R\R-2.11.0\bin\R.exe*****;
****for R-2.12.0, use: C:\Progra~1\R\R-2.12.0\bin\R.exe*****;
****for R-2.13.0, use: C:\Progra~1\R\R-2.13.0\bin\R.exe*****;
****for R-2.14.0, use: C:\Progra~1\R\R-2.14.0\bin\R.exe*****;
run;
data front_code after_code body_code r_code Rlog file; delete; run;
data body_code;
infile "&saswork\&r_code..r" length=len;
input var1 $varying8192. len;
run;
data _null_;
call symput('sasdirec',"&saswork");
call symput('rdirec',trim(left(tranwrd("&saswork",'\','/'))));
call symput('rsaswork',trim(left(tranwrd("&saswork",'\','/'))));
run;
*****determine if customer defined code produce fixed figure*****;
%let crfg=0;
%let userdefloc=0;
data _null_;
set body_code;
if index(lowcase(var1),'setwd') and
(index(lowcase(var1),'#')=0 or index(lowcase(var1),'#')> index(lowcase(var1),'setwd')) then do;
call symput('userdefloc','1');
directory=scan(var1,2,'(');
directory=compress(directory,'"();');
directory=compress(directory,"'");
call symput('rdirec',trim(left(directory)));
directory=tranwrd(directory,'/','\');
call symput('sasdirec',trim(left(directory)));
end;
if index(lowcase(var1),'.gif') or index(lowcase(var1),'.jpeg') or index(lowcase(var1),'.jpg')
or index(lowcase(var1),'.png') or index(lowcase(var1),'.ps') then call symput('crfg','1');
run;
*******convert sas file to csv for R import******;
%let i=1;
%do %while(%scan(&_sas2R,&i,%str( )) ne);
%let transfer=%scan(&_sas2R,&i,%str( ));
%let i=%eval(&i+1);
proc export data=&transfer outfile="&sasdirec/&transfer..csv" replace; run;
%end;
****get current time before run batch R***;
data _null_;
call symput('nowtime',trim(left(scan(put(datetime(),best.),1,'.'))));
run;
%put $$$$&nowtime;
data front_code;
length var1 $1000;
format var1 $1000.;
%if &userdefloc=0 %then %do;
var1='setwd("'||"&rsaswork"||'")'; output;
%end;
var1='library(grDevices)'; output;
%if &crfg=0 %then %do;
var1='png("'||"&rdirec/_&nowtime"||'.png")'; output;
%end;
******prepare R code use dataframe to read in SAS dataset via CSV****;
%let i=1;
%do %while(%scan(&_sas2r,&i,%str( )) ne);
%let transfer=%scan(&_sas2r,&i,%str( ));
%let i=%eval(&i+1);
var1="&transfer"||"<- read.csv('"||"&rdirec/&transfer..csv"||"')";
output;
%end;
run;
data after_code;
length var1 $1000;
format var1 $1000.;
******prepare R code to output csv file for sas import****;
%let i=1;
%do %while(%scan(&_R2SAS,&i,%str( )) ne);
%let transfer=%scan(&_R2SAS,&i,%str( ));
%let i=%eval(&i+1);
var1="write.csv(&transfer,'"||"&transfer..csv"||"',row.names=F)";
output;
%end;
%if &crfg=0 %then %do;
var1='dev.off()'; output;
%end;
var1='q()'; output;
run;
*****update R code*****;
data r_code;
set front_code body_code after_code;
run;
data _null_;
file "&saswork/&r_code..r";
set r_code;
put var1;
run;
****get current time before run batch R***;
data _null_;
call symput('beforetm',trim(left(put(datetime(),datetime19.))));
run;
%put $$$$&beforetm;
%let _saswork=%bquote("&rsaswork/&r_code..r");
%let _rdirec=%bquote("&rdirec/r_log_&nowtime..txt");
options noxwait xsync;
filename proc_r pipe "&rpath CMD BATCH --vanilla --quiet
&_saswork &_rdirec";
data _null_;
infile proc_r;
run;
****get current time after run batch R***;
data _null_;
call symput('aftertm',trim(left(put(datetime(),datetime19.))));
run;
%put $$$$&aftertm;
data rlog;
infile "&sasdirec\r_log_&nowtime..txt" length=len;
input var1 $varying8192. len;
run;
data rlog;
set rlog;
var1=trim(left(var1));
run;
title "******************R OUTPUT***********************";
proc print data=rlog(rename=(var1=R_OUTPUT_LOG)) noobs; run;
title;
*****display R graphics*****;
%let _sasdirec=%bquote("&sasdirec");
FileName MyDir Pipe "dir &_sasdirec /a:-d";
data file;
infile MyDir lrecl=300 truncover;
input @1 file $100. @;
format file $100.;
crtime=substr(file,1,20);
if trim(left(scan(lowcase(file),2,'.'))) in ('gif','png','jpeg','jpg','ps') then do;
_crtime=input(crtime,mdyampm.);
temp=tranwrd(file,trim(left(crtime)),'*');
temp=scan(temp,1,'*');
filename=trim(left(scan(temp,2,' ')));
end;
run;
proc sort data=file; by descending _crtime descending filename;
where trim(left(scan(lowcase(file),2,'.'))) in ('gif','png','jpeg','ps');
run;
data _null_;
set file;
if _n_=1 then do;
call symput('fgsw',put(input("&beforetm",datetime19.)<(input(crtime,mdyampm.)+60),best.));
temp=tranwrd(file,trim(left(crtime)),'*');
temp2=scan(temp,1,'*');
fgname=scan(temp2,2,' ');
call symput('fgname',trim(left(fgname)));
end;
run;
%put $$$$&fgname;
%if &fgsw=1 %then %do;
ODS ESCAPECHAR='^';
ODS HTML FILE="&sasdirec\rhtml_&nowtime..html" STYLE=minimal
GPATH="&sasdirec\" GTITLE GFOOTNOTE;
ods listing close;
%global inhtml;
%let inhtml=%bquote("&sasdirec\&fgname");
DATA _NULL_;
FILE PRINT;
PUT "<IMG src=&inhtml BORDER='0'>";
RUN;
ods html close;
ods listing;
/*
goptions reset=all device=win;
goptions iback="&rdirec\&fgname" imagestyle=fit;
proc gslide;
run;
quit;
*/
%end;
*******convert csv file from R to SAS file******;
%let i=1;
%do %while(%scan(&_R2SAS,&i,%str( )) ne);
%let transfer=%scan(&_R2SAS,&i,%str( ));
%let i=%eval(&i+1);
proc import datafile="&sasdirec/&transfer..csv" out=&transfer replace; guessingrows=1000; run;
%end;
*options notes;
%mend;
... View more