Call System output in Macro Variable - macros

I want to get the file size of a csv file in AIX and using following X and Call System Command to do. The problem is I cant get the "File Size" in a macro variable which I will be using later in the program.
data _null_;
call system('du -g p_bhj_c_hh100uk01po1.csv');
call symput('space','X du -g p_bhj_c_hh100uk01po1.csv');
%put &space;
run;
WARNING: Apparent symbolic reference SPACE not resolved.

First, the SYMPUT subroutine you call does not work like you are trying to use it (ala Perl). I recommend reading the documentation on it.
The error you get on the SPACE macro is because it is inside the DATA Step. Macros "write" SAS code for you, so it &SPACE macro is trying to be resolved BEFORE the DATA Step executes.
Here is a code example to do what you are looking for:
data _null_;
rc = filename("ref","e:\temp\reg.pdf");
fid = fopen("ref");
infonum = foptnum(fid);
do i=1 to infonum;
infoname = foptname(fid,i);
infoval=finfo(fid,infoname);
put infoname= infoval=;
end;
close = fclose(fid);
run;
/*In Windows, attribute is "File Size (bytes)"*/
data _null_;
rc = filename("ref","e:\temp\reg.pdf");
fid = fopen("ref");
size=finfo(fid,"File Size (bytes)");
call symput("size",size);
close = fclose(fid);
run;
%put &size;
The File Size attribute may be different in AIX. Run the first part to see all the attributes available. Then modify the second accordingly. Likewise, you will need to add the call to produce the file like you are already doing.

Related

Edit an Abaqus input file and Run it from Matlab

I need perform 50 Abaqus simulations, each simulation analyses a certain material property and each differs by changing one parameter. So the idea is to write a Matlab script that:
opens the .inp file
edits the material parameter of interest
prints it into a new file which will be the new .inp file
runs it to perform the simulation
This is what I accomplished so far in a very simplified version:
f= fopen('PRD8_30s.inp');
c = textscan(f,'%s %s %s %s %s ','delimiter',',');
fclose(f) ;
S = [c{1}];
A = {'5e-08'} ;
S(12496) = A ;
fid = fopen('file.inp','w') ;
fprintf(fid,'%s \n',S{:} );
fclose(fid) ;
PRD_8_30s.inp
I manually found out the position of the parameter of interest (A at 12496 hence below the line *Viscoelastic). The code actually changes the parameter I need but there are major problems: it prints a new file with additional lines with respect to the original .inp (12552 vs 8737) and it doesn't print the entire .inp but only the first column.
How can I edit the .inp changing the parameter and obtaining a new .inp with the edited parameter that can be used to run the new simulation?
Thank you in advance for your help!
If your input file is not multiple Gb in size, The following might help.
create a template input and mark the parameter you want to change as, for example para_xxxx
Use the following script:
text=fileread('template.inp');
newtext=replace(text,'para_xxxx',newParameter);
fid=fopen('newcase.inp','w');
fprintf(fid,newtext);
fclose(fid);
The file name 'newcase.inp' should be updated each time in the loop.

SAS include dynamic path

I have tryed build little macro which in loop it should runother SAS programs.
Table Control_files has two field, where are other part of path to proper sas program.
%LET PATH_TO = '%include "T:\XXX\YYY\ZZZ\';
%LET PATH_end = '.sas"';
data _null_;
set CONTROL_FILES;
call execute ('%runlimitsquery('||&PATH_TO||SCHEMA_NAME||'\'||PROCES_NAME||&PATH_end||');');
run;
I tryed used runlimitsquery because I found somewhere that tip..
When I run my code, log returns:
NOTE: CALL EXECUTE generated line.
NOTE: Line generated by the CALL EXECUTE routine.
1 + %runlimitsquery(%include "T:\XXX\YYY\ZZZ\XXX_TECHNICAL_AAAAA\001_AAAAA.sas");
_
180
WARNING: Apparent invocation of macro RUNLIMITSQUERY not resolved.
ERROR 180-322: Statement is not valid or it is used out of proper order
Anyone can help me?
Ok, I have answer for my problem...
Below code works:
%LET PATH_TO = '%include "T:\XXX\YYY\ZZZ\';
%LET PATH_end = '.sas"';
data _null_;
set CONTROL_FILES;
call execute ('('||&PATH_TO.||SCHEMA_NAME||'\'||PROCES_NAME||&PATH_end.||';');
run;

run script command in Matlab

I am running a script in another directory.
Assume I have the following code:
arr = [10;20;30];
run(script); % script= path to the script file + scriptfile.mat ..
x = arr(2);
It gave me the following error:
Undefined function 'arr' for input arguments of type 'double'.
After debugging the code, I found that run(script) .. run the script and then clear all variables .. such as arr.
Is there any way to make run command doesn't clear all variables..
Edit: the following is the original code..
xValues =[2;4;6];
yValues =[10;15;20;30;40];
for var1 =1:size(xValues,1)
results =[];
for var2 =1: size(yValues,1)
run(strcat('C:\Users\as\Desktop\study',num2str(xValues(var1)),'folder\',num2str(yValues(var2)),'folder\file1.m'));
results(var2,1) = yValues(var2);
end
end
Thanks,
Here is an example, erase clear command in your script file:
testing.m
arr = [10;20;30];
run('ScriptFile.m')
x = arr(2);
ScriptFile.m
disp('Hello World');
Command Window
Hello World
After the implementation x holds number 20.
It is clear all inside your script doing the mess I believe.
As for how to avoid it:
Simply remove it. This is generally the easiest and best solution.
Write file to the disk, run script, load from disk. You need a hardcoded file name.
Create "data_holding_function" that has persistent cell array, you load your data there and then restore it after script. You can make the function perform both loading (when you have some input) and unloading (when you don't).

How to write macro for importing multiple excel files(xlsx) in sas and append it

I am having some 50 excel files (xlsx format) to be imported to sas and then need to append it for analysis. All the excel files header are same i.e., the variable names are same for all the file. I need macro for importing and appending all of them at a time rather than importing all the files one by one and then later append it. Your help is much appreciated.
The other issue with the excel file is that there is a blank column next between the variable name and data points. I have written a code remove it using data step but came we write this also in the macro while importing.
Data XXX.yyy;
Set XXX.yyy;
if missing(coalesceC(of ASC Brand Cdesc1 Cust_ DGM Desc Family Grp1 High_Level_Product_Desc
Issf Name Prod_Desc Product__Code RVP SA_Desc Terr_ UOM Yr
)) and missing(coalesce(of Acc Int_Margin M_Cost Mth Net_Sales Sls__ Uts )) then delete;
run;
It sounds as though your existing code already does what you need it to do. I doubt there will be much of a performance gain from attempting to import all 50 files in one data step (which is possible via dde, but rather fiddly).
If your existing code is set up to process just one hard-coded file, I'd suggest using it to write a simple macro that takes one excel file as input, imports that file, and appends it to the master dataset. Then you can call the macro 50 times.
e.g. You could write the macro as something like this, incorporating all the relevant bits of your code, and replacing all references to specific files with macro variables:
%macro import_and_append(excel_file,base_dataset);
proc import datafile = "&excel_file" dbms = excel out = t_import;
run;
proc append base = &base_dataset data = t_import;
run;
proc datasets lib = work nolist nowarn;
delete t_import;
run;
quit;
%mend;
Then you can call the macro like so:
%import_and_append(c:\excel_file_01.xls,work.master_dataset)
Another way to do this would be to use the Excel LIBNAME Engine. You declare a library to each of your files, and then read all the sheets in 1 Data Step.
In this example, I have 2 workbooks (Book1.xlsx and Book2.xlsx) in C:\temp. All data is in Sheet1. 3 variables -- X, Y, and Z. Modify as needed for your purpose.
data files;
format file $12.;
input file $;
datalines;
Book1.xlsx
Book2.xlsx
;
run;
%macro read_excel(dir,outdata,files);
data _null_;
set &files end=last;
call execute("libname t" || strip(put(_n_,8.)) || " excel '&dir\" || strip(file) || "';");
if last then
call symput("n",_n_);
run;
data &outdata;
set
%do i=1 %to &n;
t&i.."Sheet1$"n
%end;
;
a = sum(x,y,z);
if missing(a) then delete;
run;
%do i=1 %to &n;
libname t&i clear;
%end;
%mend;
%read_excel(c:\temp,data_from_excel,files);

save svm models to file matlab

I have 31 models an I want to save each one in a specific file
this is my matlab function
formatspec='model%d'
for k = 1:length(libsvmFiles)
baseFileName = libsvmFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
[labels train]=libsvmread(fullFileName);
model=svmtrain(labels,train, '-t 2 -h 0');
file=sprintf(formatspec,k);
save file model;
but the problem is only the first file is saved and its name is 'file' tha's mean the value of the variable file is not evaluated
how can I solve this problem ?
As many Matlab functions, save can be used in function form (save(...)) or in command form (save ...). In the command form that you use, all the arguments are interpreted as strings. That means
save file model
is equivalent to
save('file', 'model')
For the second argument that is correct, because you want to refer to the variable with the name "model". For the first argument it is wrong, because you want to refer to the file name contained in the variable file. The correct syntax to use is therefore
save(file, 'model')
You're missing the parens for the save function. The model variable also needs to be listed as a string since you need to tell the save function the name of the variable, not the variable itself. See Matlab's documentation.
save(file, 'model');
Additionally you don't have an end to your for loop shown, which normally would just throw an error -- however later code might cause this loop to instead only run once. Otherwise you should check your libsvmFiles variable as it might be only length 1 or not be an array.