SAS - ODS zip file issue - no logical assign? - zip

I'm having issues with the foloowing code and I can't seem to find much information to help me sort it out. I'm trying to write some filenames from a directory to a datset, then create a zip file of those files. It works fine until I reach the data step with the infile statement. I received the following error...
ERROR: No logical assign for filename DIRLIST.
Here is my code...
%macro get_filenames(location);
filename _dir_ "%bquote(&location.)";
data filenames(keep=fname);
handle=dopen( '_dir_' );
if handle > 0 then do;
count=dnum(handle);
do i=1 to count;
fname=dread(handle,i);
output filenames;
end;
end;
rc=dclose(handle);
run;
filename _dir_ clear;
%mend;
%get_filenames(c:\temp\);
data dirlist;
set filenames;
where fname like 'scra%.txt';
run;
ods package(testfile) open nopf;
data _null_;
infile dirlist pad lrecl=80;
input #1 filename $80.;
call execute
(catx
(' ',
'ods package(testfile)',
'add file=',
quote('c:\temp\' || trim(filename)),
';'
)
);
run;
ods package(testfile) publish archive
properties(archive_name='testfile.zip'
archive_path='c:\temp\' );
ods package(testfile) close;

I think SAS is complaining about the following in your code:
data _null_;
infile dirlist pad lrecl=80;
Infile in this context is expecting a FILENAME reference the kind you have at filename _dir_ "%bquote(&location.)";
It does not understand that you want to use the dataset dirlist.
Replace the above code snippet with the following:
data _null_;
SET dirlist;

Related

SAS script works in windowing environment but fails in Linux

The code works very good, and creates the data, but in Linux it says the the data has 0 observations.
It has to search in library the files with specific name (and date in name).
%let path=library.name;
%let fname=name.starts.with;
data fnames;
length
fref $8
fname $200
datestr $17
;
format fdate yymmdd10.;
rc = filename(fref,"&path.");
did = dopen(fref);
if did ne 0
then do;
do i = 1 to dnum(did);
fname = dread(did,i);
if index(fname,"&fname.")
then do;
datestr = scan(scan(fname,-2,"."),-1,"_");
date = input(substr(datestr,1,8),yymmdd8.);
fdate = substr(datestr,1,8);
output;
end;
end;
rc = dclose(did);
end;
rc = filename(fref);
keep fname fdate;
run;
proc sort data=fnames;
by descending fdate;
run;
data _null_;
set fnames (obs=1);
call symputx("fdate",fdate,"g");
run;
How can I run the code in Linux? Why is it not read the data correctly?
Thank you.

How to read CSV files with GNU Octave if the delimiter is ;?

I have an .csv file made in Excel and that Excel uses ; as delimiter. I don't like that, but I cannot change it.
So I have to accept it.
I want to read that .csv file in GNU Octave, but I can't really do it because the float numbers inside the .csv file is separated with , e.g 15,25 and not separated with . e.g 15.25 because in Excel, it assumes that 15.25 is a text string and 15,25 is a number. Yes, I know, it's weird.
If I change all , to . in my .csv file, then I can read the .csv file with dlmread or csvread. But in this case, I don't want to change , to . because that's a standard Excel configuration.
So my question is:
If you have a .csv file were the float numbers are displayed with ,. How can you read that .csv file in GNU Octave then?
For a much more flexible csv reader than the default matlab-compatible csvread and dlmread, use the csv2cell function from the io pkg. If you haven't used packages before, this is how you would do that:
pkg install io -forge % install io package if you haven't already
pkg load io % load it
Then use csv2cell to read the values as strings into a cell (declaring ; as the desired delimiter); then use strrep to replace , to . in your strings; and then finally use str2double to convert those strings to numbers.
You can do this with the following one-liner:
str2double( strrep( csv2cell( 'testo.csv', ';' ), ',', '.' ) )
You could also wrap this into an anonymous function:
read_my_csv = #( myfile ) str2double( strrep( csv2cell( myfile, ';' ), ',', '.' ) );
Data = read_my_csv( 'data.csv' );
PS. Tux the penguin added for extra perfection, as requested.
_nnnn_
dGGGGMMb ,"""""""""""""".
#p~qp~~qMb | Linux Rules! |
M|#||#) M| _;..............'
#,----.JM| -'
JS^\__/ qKL
dZP qKRb
dZP qKKb
fZP SMMb
HZM MMMM
FqM MMMM
__| ". |\dS"qML
| `. | `' \Zq
_) \.___.,| .'
\____ )MMMMMM| .'
`-' `--'
(source: https://www.asciiart.eu/computers/linux)
Sample file
i1;i2;i3
1,234;34,134;5,987
3,14;6,96;85,05
Script
nrows = 2;
ncolumns = 3;
data = textscan (fopen("data.csv", 'r'), "%s", "Delimiter", ";", "HeaderLines", 1);
data = cell2mat(data);
data = str2double(strrep(data,',','.'));
data = reshape(data, ncolumns, nrows); % elements are accessed in column-major order
data = transpose(data)
Logic
We read the contents of the file as strings separated by ;.
We replace the , present in the strings with ..
Convert the strings to doubles.
The data is reshaped to a matrix.
References
Specify decimal separator for .dat file in matlab

How to write .dsv file into dynamic folders in U-SQL script

I am new to U-SQL and am trying to read multiple .dsv files from a folder and write the output as .dsv files in dynamic folder/sub folder. So far I have successfully read multiple .dsv files and am able to write the files in a single location(pre-defined location) but am not able to write the .dsv files into multiple folders/subfolders. The folders and subfolders are defined based on the file name. As an example, If the file name is ABC_20200421#015814.dsv, it should be reading data from the .dsv file and write it into folder system: test/ABC/2020/04/21/File_Data.dsv
The code I have so far is :
DECLARE #ImportFile string = "*.dsv";
-- To read all the .dsv files and move them to folder locations
DECLARE #Code String = #ImportFile.Substring(0, 3);
DECLARE #CommanName String = #ImportFile.Substring(4, 14); File_Contents
DECLARE #Year String = #ImportFile.Substring(18, 4);
DECLARE #Month String = #ImportFile.Substring(22, 2);
DECLARE #File_Date String = #ImportFile.Substring(24, 2);
#result=
SELECT col1,col2,col3
FROM Table1
//Writing to dsv file:
OUTPUT #result
TO "test/"+#Code+"/"+#Year+"/"+#Month+"/"+#File_Date+"/File_Data.dsv"
USING Outputters.Text(delimiter : '|', quoting: false);
On running the code, I get an error:
E_CSC_USER_EXPRESSIONNOTCONSTANTFOLDABLE: Expression cannot be constant folded.
Details:
at token '"/test/"', near the ###:
OUTPUT #result TO ### "/test/"+#Code+"/"+#Year+"/"+#Month+"/"+#File_Date+"/STAY_REVENUES.dsv" USING Outputters.Text(delimiter : '|', quoting : false)
Any help would be appreciated. Thanks in advance.

SAS - duplicate excel file in another folder

If i have an Excel "Covid19_report &todaysdate. &time..xlsx" file in a folder called F:\A
and I want to put this exact file into folder F:\B but duplicated 6 times like this:
"1_Covid19_report &todaysdate. &time..xlsx"
"2_Covid19_report &todaysdate. &time..xlsx"
"3_Covid19_report &todaysdate. &time..xlsx"
"4_Covid19_report &todaysdate. &time..xlsx"
"5_Covid19_report &todaysdate. &time..xlsx"
"6_Covid19_report &todaysdate. &time..xlsx"
is there a macro to do that?
The SAS function FCOPY will be helpful.
Copying binary files requires a fileref be created with options such as RECFM=N and LRECL=<filesize>
Example:
Create a sample Excel file and copy it 6 times to target files having an index prefix in their filenames.
* Create sample Excel file for copying;
ods noresults;
ods excel file='c:\temp\prices.xlsx';
proc print data=sashelp.stocks;
run;
ods excel close;
ods results;
* Copy a source file 6 times to a target file with an index number prefix name pattern;
data _null_;
length source_ref target_ref $8;
* determine name part from full pathname;
source_file = 'c:\temp\prices.xlsx';
source_name = scan(source_file,-1,'\');
* determine source file size for efficient options;
* NOTE: FCOPY only works on files < 1G in size;
rc = filename(source_ref, source_file);
fid = fopen(source_ref);
bytes = finfo(fid,'File size (bytes)');
fid = fclose(fid);
rc = filename(source_ref);
options = 'recfm=n lrecl='||trim(bytes);
* prepare SOURCE fileref;
source_ref = '';
rc = filename(source_ref, source_file, 'DISK', options);
* duplicate in same folder (via transtrn);
do index = 1 to 6;
* compute target file name and corresponding full path;
target_name = cats(index,"_",source_name);
target_file = transtrn(source_file, trim(source_name), target_name);
* create temporary TARGETR fileref (due to ref value passed in being blank);
target_ref = '';
if 0 = filename (target_ref, target_file, 'DISK', options) then do;
rc = fcopy ('source', target_ref);
rc = filename(target_ref); * clear TARGET fileref;
end;
end;
stop;
run;
i tried doing this, but do not work:
%let todaysDate = %sysfunc(today(), yymmdd10.); %put &todaysDate;
data _null_; ftime = intnx('hour',time(),0,'b'); cftime =
compress(put(ftime,hhmm.),":"); call symputx("ftime",cftime); run;
%put &=ftime.;
%let path = F:\A;
%let file = COVID-19 Report &todaysdate. &ftime.;
filename source "&path.\&file.";
data _null_; length target_ref $8;
do index = 1 to 6;
target_file = cats("&path.",index,"_&file.");
target_ref = '';
* create temporary fileref (due to initial ref value being blank);
if 0 = filename (target_ref, target_file) then do;
rc = fcopy ('source', target_ref);
rc = filename(target_ref);
end; end; stop; run;

How to save a table to a file from Lua

I'm having trouble printing a table to a file with lua (and I'm new to lua).
Here's some code I found here to print the table;
function print_r ( t )
local print_r_cache={}
local function sub_print_r(t,indent)
if (print_r_cache[tostring(t)]) then
print(indent.."*"..tostring(t))
else
print_r_cache[tostring(t)]=true
if (type(t)=="table") then
for pos,val in pairs(t) do
if (type(val)=="table") then
print(indent.."["..pos.."] => "..tostring(t).." {")
sub_print_r(val,indent..string.rep(" ",string.len(pos)+8))
print(indent..string.rep(" ",string.len(pos)+6).."}")
elseif (type(val)=="string") then
print(indent.."["..pos..'] => "'..val..'"')
else
print(indent.."["..pos.."] => "..tostring(val))
end
end
else
print(indent..tostring(t))
end
end
end
if (type(t)=="table") then
print(tostring(t).." {")
sub_print_r(t," ")
print("}")
else
sub_print_r(t," ")
end
print()
end
I have no idea where the 'print' command goes to, I'm running this lua code from within another program. What I would like to do is save the table to a .txt file. Here's what I've tried;
function savetxt ( t )
local file = assert(io.open("C:\temp\test.txt", "w"))
file:write(t)
file:close()
end
Then in the print-r function I've changed everywhere it says 'print' to 'savetxt'. This doesn't work. It doesn't seem to access the text file in any way. Can anyone suggest an alternative method?
I have a suspicion that this line is the problem;
local file = assert(io.open("C:\temp\test.txt", "w"))
Update;
I have tried the edit suggested by Diego Pino but still no success. I run this lua script from another program (for which I don't have the source), so I'm not sure where the default directory of the output file might be (is there a method to get this programatically?). Is is possible that since this is called from another program there's something blocking the output?
Update #2;
It seems like the problem is with this line:
local file = assert(io.open("C:\test\test2.txt", "w"))
I've tried changing it "C:\temp\test2.text", but that didn't work. I'm pretty confident it's an error at this point. If I comment out any line after this (but leave this line in) then it still fails, if I comment out this line (and any following 'file' lines) then the code runs. What could be causing this error?
I have no idea where the 'print' command goes to,
print() output goes to default output file, you can change that with io.output([file]), see Lua manuals for details on querying and changing default output.
where do files get created if I don't specify the directory
Typically it will land in current working directory.
Your print_r function prints out a table to stdout. What you want is to print out the output of print_r to a file. Change the print_r function so instead of printing to stdout, it prints out to a file descriptor. Perhaps the easiest way to do that is to pass a file descriptor to print_r and overwrite the print function:
function print_r (t, fd)
fd = fd or io.stdout
local function print(str)
str = str or ""
fd:write(str.."\n")
end
...
end
The rest of the print_r doesn't need any change.
Later in savetxt call print_r to print the table to a file.
function savetxt (t)
local file = assert(io.open("C:\temp\test.txt", "w"))
print_r(t, file)
file:close()
end
require("json")
result = {
["ip"]="192.168.0.177",
["date"]="2018-1-21",
}
local test = assert(io.open("/tmp/abc.txt", "w"))
result = json.encode(result)
test:write(result)
test:close()
local test = io.open("/tmp/abc.txt", "r")
local readjson= test:read("*a")
local table =json.decode(readjson)
test:close()
print("ip: " .. table["ip"])
2.Another way:
http://lua-users.org/wiki/SaveTableToFile
Save Table to File
function table.save( tbl,filename )
Load Table from File
function table.load( sfile )

Resources