<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Replacing ODS HTML output for Enterprise Guide in ODS and Base Reporting</title>
    <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Needing-a-PIPE-error-workaround-without-allowing-XCMD/m-p/344803#M18201</link>
    <description>&lt;P&gt;Cynthia,&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks so much for this post, and for your questions. They have helped point me in the right direction. I've edited my post, which might make more sense now.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Sincerely,&lt;/P&gt;&lt;P&gt;Teresa&lt;/P&gt;</description>
    <pubDate>Mon, 27 Mar 2017 21:10:41 GMT</pubDate>
    <dc:creator>schmidtt</dc:creator>
    <dc:date>2017-03-27T21:10:41Z</dc:date>
    <item>
      <title>Needing a PIPE error workaround without allowing XCMD</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Needing-a-PIPE-error-workaround-without-allowing-XCMD/m-p/343523#M18180</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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.&amp;nbsp;Xin Wei, which I'll paste at the bottom of this post. Dr. Wei's JSTAT article (see:&amp;nbsp;&lt;A href="https://www.jstatsoft.org/article/view/v046c02" target="_blank"&gt;https://www.jstatsoft.org/article/view/v046c02&lt;/A&gt;) there has some great starter code, which I've been trying out. But they all result in PIPE errors. Here's an example:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;BR /&gt;data test;&lt;BR /&gt;do x=1 to 4;&lt;BR /&gt;array a[4] a1-a4;&lt;BR /&gt;do i=1 to 4;&lt;BR /&gt;a[i] = rannor(100);&lt;BR /&gt;end;&lt;BR /&gt;output;&lt;BR /&gt;end;&lt;BR /&gt;drop i x;&lt;BR /&gt;run;&lt;BR /&gt;&lt;BR /&gt;%include "e:\sasroot\Proc_R\Proc_R.sas";&lt;BR /&gt;%Proc_R (SAS2R = test, R2SAS =);&lt;BR /&gt;cards4;&lt;BR /&gt;R&amp;gt; testm &amp;lt;- as.matrix(test)&lt;BR /&gt;R&amp;gt; eigen(testm)&lt;BR /&gt;;;;;&lt;BR /&gt;%quit;&lt;BR /&gt;&lt;BR /&gt;---&lt;BR /&gt;ERROR: Insufficient authorization to access PIPE.&lt;BR /&gt;ERROR: Error in the FILENAME statement.&lt;BR /&gt;&lt;BR /&gt;ERROR: No logical assign for filename PROC_R.&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have seen solutions to PIPE errors (e.g., &lt;A href="http://support.sas.com/kb/41/058.html" target="_blank"&gt;http://support.sas.com/kb/41/058.html&lt;/A&gt;) by&amp;nbsp;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&amp;nbsp;&lt;A href="https://www.jstatsoft.org/article/view/v046c02" target="_blank"&gt;https://www.jstatsoft.org/article/view/v046c02&lt;/A&gt;) 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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt; ***********************************************************************************************************************
 ***********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=&amp;amp;SAS2R;
%let _R2SAS=&amp;amp;R2SAS;
%let saswork=%sysfunc(pathname(work));
data _null_;
    call symput('r_code','r_code'||trim(left(scan(put(datetime(),best.),1,'.'))));
run;
%put &amp;amp;r_code;
data _null_;
     file "&amp;amp;saswork\&amp;amp;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 "&amp;amp;saswork\&amp;amp;r_code..r" length=len;
     input var1 $varying8192. len;
run;
data _null_;
	 call symput('sasdirec',"&amp;amp;saswork");
	 call symput('rdirec',trim(left(tranwrd("&amp;amp;saswork",'\','/'))));
	 call symput('rsaswork',trim(left(tranwrd("&amp;amp;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),'#')&amp;gt; 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(&amp;amp;_sas2R,&amp;amp;i,%str( )) ne);
    %let transfer=%scan(&amp;amp;_sas2R,&amp;amp;i,%str( ));
	%let i=%eval(&amp;amp;i+1); 
    proc export data=&amp;amp;transfer outfile="&amp;amp;sasdirec/&amp;amp;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 $$$$&amp;amp;nowtime;

data front_code;
     length var1 $1000;
	 format var1 $1000.;
	 %if &amp;amp;userdefloc=0 %then %do;
         var1='setwd("'||"&amp;amp;rsaswork"||'")'; output;
	 %end;
	 var1='library(grDevices)'; output;
	 %if &amp;amp;crfg=0 %then %do;
	     var1='png("'||"&amp;amp;rdirec/_&amp;amp;nowtime"||'.png")'; output;
	 %end;
	 ******prepare R code use dataframe to read in SAS dataset via CSV****;
	 %let i=1;
     %do %while(%scan(&amp;amp;_sas2r,&amp;amp;i,%str( )) ne);
     %let transfer=%scan(&amp;amp;_sas2r,&amp;amp;i,%str( ));
	 %let i=%eval(&amp;amp;i+1); 
          var1="&amp;amp;transfer"||"&amp;lt;- read.csv('"||"&amp;amp;rdirec/&amp;amp;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(&amp;amp;_R2SAS,&amp;amp;i,%str( )) ne);
     %let transfer=%scan(&amp;amp;_R2SAS,&amp;amp;i,%str( ));
	 %let i=%eval(&amp;amp;i+1); 
          var1="write.csv(&amp;amp;transfer,'"||"&amp;amp;transfer..csv"||"',row.names=F)";
	      output;
	 %end;
 	 %if &amp;amp;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 "&amp;amp;saswork/&amp;amp;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 $$$$&amp;amp;beforetm;

%let _saswork=%bquote("&amp;amp;rsaswork/&amp;amp;r_code..r");
%let _rdirec=%bquote("&amp;amp;rdirec/r_log_&amp;amp;nowtime..txt");

options noxwait xsync; 
filename proc_r pipe "&amp;amp;rpath CMD BATCH --vanilla --quiet
                    &amp;amp;_saswork  &amp;amp;_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 $$$$&amp;amp;aftertm;

data rlog;
     infile "&amp;amp;sasdirec\r_log_&amp;amp;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("&amp;amp;sasdirec");
FileName MyDir Pipe "dir &amp;amp;_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("&amp;amp;beforetm",datetime19.)&amp;lt;(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 $$$$&amp;amp;fgname;
%if &amp;amp;fgsw=1 %then %do;

ODS ESCAPECHAR='^';
ODS HTML FILE="&amp;amp;sasdirec\rhtml_&amp;amp;nowtime..html" STYLE=minimal
GPATH="&amp;amp;sasdirec\" GTITLE GFOOTNOTE;
ods listing close;
%global inhtml;
%let inhtml=%bquote("&amp;amp;sasdirec\&amp;amp;fgname");
DATA _NULL_;
FILE PRINT;
PUT "&amp;lt;IMG src=&amp;amp;inhtml BORDER='0'&amp;gt;";
RUN;
ods html close;
ods listing;
/*
goptions reset=all device=win;
goptions iback="&amp;amp;rdirec\&amp;amp;fgname" imagestyle=fit; 
proc gslide;
run;
quit; 
*/

%end;
*******convert csv file from R to SAS file******;
%let i=1;
%do %while(%scan(&amp;amp;_R2SAS,&amp;amp;i,%str( )) ne);
    %let transfer=%scan(&amp;amp;_R2SAS,&amp;amp;i,%str( ));
	%let i=%eval(&amp;amp;i+1); 
    proc import datafile="&amp;amp;sasdirec/&amp;amp;transfer..csv" out=&amp;amp;transfer replace; guessingrows=1000; run;
%end;


*options notes;
%mend;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 27 Mar 2017 21:18:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Needing-a-PIPE-error-workaround-without-allowing-XCMD/m-p/343523#M18180</guid>
      <dc:creator>schmidtt</dc:creator>
      <dc:date>2017-03-27T21:18:54Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing ODS HTML output for Enterprise Guide</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Needing-a-PIPE-error-workaround-without-allowing-XCMD/m-p/343537#M18181</link>
      <description>Hi:&lt;BR /&gt;  I don't see where the value of &amp;amp;sasdirec or &amp;amp;inhtml are being set. I am not sure I understand how the macro you show as Proc_R.sas is being invoked. You might wish to contact the author of the macro program for more direct help.&lt;BR /&gt;&lt;BR /&gt;cynthia</description>
      <pubDate>Wed, 22 Mar 2017 23:51:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Needing-a-PIPE-error-workaround-without-allowing-XCMD/m-p/343537#M18181</guid>
      <dc:creator>Cynthia_sas</dc:creator>
      <dc:date>2017-03-22T23:51:51Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing ODS HTML output for Enterprise Guide</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Needing-a-PIPE-error-workaround-without-allowing-XCMD/m-p/344803#M18201</link>
      <description>&lt;P&gt;Cynthia,&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks so much for this post, and for your questions. They have helped point me in the right direction. I've edited my post, which might make more sense now.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Sincerely,&lt;/P&gt;&lt;P&gt;Teresa&lt;/P&gt;</description>
      <pubDate>Mon, 27 Mar 2017 21:10:41 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Needing-a-PIPE-error-workaround-without-allowing-XCMD/m-p/344803#M18201</guid>
      <dc:creator>schmidtt</dc:creator>
      <dc:date>2017-03-27T21:10:41Z</dc:date>
    </item>
  </channel>
</rss>

