How to work on SAS Data - python-2.7

I am working on SAS from the past 5 years and I am aware of only Base SAS ,SAS macro and Proc SQL and no other languages. Recently management has decided to migrate all the SAS code into python and they wanted us to learn PYTHON and convert all SAS codes into PYTHON(Thanks to Management). I am very much confused how to get started on this, I have read through some python online materials but I am wondering how to convert all the SAS code into python. To get started Can you please help me on the below sample SAS code how do we convert this in Python,
Please assume I have sample raw_data as following,
Name Age Val
Abc 23 100
Pqr 24 200
Xyz 26 400
I have below code which is the starting ,
%if %sysfunc(exist(raw_data)) eq 0 %then %do;
Data old_data;
set raw_data(where age>=24);
run;
%end;
proc sort data=olddata out=newdata;
by name descending val;
run;
Thanks in advance for your Help,
Regards,
Surya...

Related

SAS Proc Freq Not Displaying Values

I am doing some simple cross tabulations using Proc Freq, but I'm noticing that the output SAS gives me doesn't contain any frequency counts; I'm only getting percents.
Here is an example code that I ran in SAS (I am using SAS 9.4):
data test;
input year 1-5 group $6;
cards;
2018 A
2018 A
2018 B
2018 B
2019 A
2019 A
2019 A
2019 B
;
run;
proc freq data = test;
table year * group / norow nopercent;
run;
I'm expecting a table that has the frequency counts with the column percentage below, but instead, this is what SAS is giving me:
Does anyone know how I can get the frequency values to be shown?
I ran your code and got this. I reckon there is something you are not telling us.
Thank you all for your help- I found the issue. It looks like there was an issue with the cross-tab frequency template that came with SAS. I was able to restore it by using the following code:
proc template;
delete base.freq.crosstabfreqs;
run;
Thank you all for your help!
#_null_ your image is NOT the output I get when running the questions code.
The Frequency and Col Pct are NOT in row header cells, and instead are shown in a box offset to the left from the table.

Trying to get file attributes (file size , create date time and last modified date time) in SAS

I'm using following macro to get Linux file attributes using SAS. I'm getting values for size and Last modified time but not getting any values for "Create Date Time".
%macro FileAttribs(filename);
%local rc fid fidc;
%local Bytes CreateDT ModifyDT;
%let rc=%sysfunc(filename(onefile,&filename));
%let fid=%sysfunc(fopen(&onefile));
%let Bytes=%sysfunc(finfo(&fid,File Size (bytes)));
%let CreateDT=%sysfunc(finfo(&fid,Create Time));
%let ModifyDT=%sysfunc(finfo(&fid,Last Modified));
%let fidc=%sysfunc(fclose(&fid));
%let rc=%sysfunc(filename(onefile));
%put NOTE: File size of &filename is &Bytes bytes;
%put NOTE: Created &CreateDT;
%put NOTE: Last modified &ModifyDT;
%mend FileAttribs;
%FileAttribs(/path/test.csv);
I couldn't figure what I'm missing.
Are there any other file attributes that we can get other than size, create and modified dates?
Thanks,
Sampath.
According to this answer, many Linux systems don't store file creation date (or if they store it, it's not accessible with a standard name): https://unix.stackexchange.com/questions/91197/how-to-find-creation-date-of-file .
If you want to get the value of all file attributes available via the FINFO(), you can use FOPTNUM() to find the number of attributes available, and then loop over them. Here is a macro:
%macro GetAllAttributes(file);
%local rc fref fid i AttributeName AttributeValue;
%let rc=%sysfunc(filename(fref,&file));
%let fid=%sysfunc(fopen(&fref));
%do i=1 %to %sysfunc(foptnum(&fid));
%let AttributeName=%sysfunc(foptname(&fid,&i));
%let AttributeValue=%sysfunc(finfo(&fid,&AttributeName));
%put &AttributeName : &AttributeValue;
%end;
%let fid=%sysfunc(fclose(&fid));
%let rc=%sysfunc(filename(fref));
%mend GetAllAttributes;
On Windows (SAS 9.3) I get:
78 %GetAllAttributes(d:\junk\somefile.txt)
Filename : d:\junk\somefile.txt
RECFM : V
LRECL : 256
File Size (bytes) : 1011
Last Modified : 06Dec2013:14:14:54
Create Time : 06Dec2013:14:14:52
On Linux (SAS 9.3) I get:
41 %GetAllAttributes(~/somefile.txt)
Filename : /home/Quentin/somefile.txt
Owner Name : Quentin
Group Name : somegroup
Access Permission : rwx------
Last Modified : Fri Dec 6 14:14:54 2013
File Size (bytes) : 1011
Lastly, note that SAS 9.3 on Linux returns the modified date in an ugly format. Tech support told me that 9.4 returns a SAS-friendly date-time format like Windows does. If you're on 9.3, see this question for advice on parsing the date: SAS macro function to get file modified date on linux.
For a list of what's available, you can see the SAS Documentation for FINFO in Unix. That isn't updated for the additions you note above, which are listed here, but they should work.
Your macro retrieves all three information bits for me, in Windows, though that's of course possibly different from Linux/Unix. The Windows documentation does list the three new items - so I wonder if there was an issue with them in Unix/Linux and they aren't fully supported in 9.3. (They're still not listed in the 9.4 docs, either, if that's relevant.)

SAS dynamically declaring macro variable

My company just switched from R to SAS and I am converting a lot of my R code to SAS. I am having a huge issue dynamically declaring variables (macro variables) in SAS.
For example one of my processes needs to take in the mean of a column and then apply it throughout the code in many steps.
%let numm =0;
I have tried the following with my numm variable but both methods do not work and I cannot seem to find anything online.
PROC MEANS DATA = ASSGN3.COMPLETE mean;
#does not work
&numm = VAR MNGPAY;
run;
Proc SQL;
#does not work
&numm =(Select avg(Payment) from CORP.INV);
quit;
I would highly recommend buying a book on SAS or taking a class from SAS Training. SAS Programming II is a good place to start (Programming I if you have not programmed anything else, but that doesn't sound like the case). The code you have shows you need it. It is a complete paradigm shift from R.
That said, try this:
proc sql noprint;
select mean(payment) into :numm from corp.inv;
quit;
%put The mean is: &numm;
Here's the proc summary / data step equivalent:
proc summary data = corp.inv;
var payment;
output out = inv_summary mean=;
run;
data _null_;
set inv_summary;
call symput('numm',payment);
run;
%put The mean is: &numm;
Proc sql is a more compact approach if you just want a simple arithmetic mean, but if you require more complex statistics it makes sense to use proc summary.

Convert the number of observations in a dataset into a macro variable

I am trying to determine the number of observations in a dataset, then convert this number into a macro variable that i can use as part of a loop. I've searched the web for answers and not had much luck. I would post some example code I've tried but I have literally no idea how to approach this.
Could anybody assist?
Thanks
Chris
SAS stores dataset information, such as number of observations, separately, so the key is to access this information without having to read in the entire dataset.
The following code will do just that, the if 0 part is never true so the dataset isn't read, however the information is.
data _null_;
if 0 then set sashelp.class nobs=n;
call symput('numobs',n);
stop;
run;
%put n=&numobs;
You can also get it from dictionary.tables like this:
proc sql noprint;
select nobs into :nobs
from dictionary.tables
where libname='YourLibrary' and memname='YourDatasetName';
quit;
Here it is:
Create macro variable:
data _null_;
set sashelp.class;
call symput("nbobs",_N_);
run;
See result:
%put &nbobs;
Use it:
data test;
do i = 1 to &nbobs;
put i;
end;
run;

How to rename variables dynamically in sas?

I have a sas data set. In it i have some variables following a pattern
-W 51 Sales
-W 52 Sales
-W 53 Sales
and so on.
Now i want to rename all of these variables dynamically such that W 51 is replaced by starting date of that week and the new name becomes - 5/2/2013 Sales?
The reason i want to rename them is that i have sales data of all the 53 weeks in an year and the data set would be eassier for me to understand if i had the starting date of a week instead of W(week_no) Sales as a variable name
Is there any way i can do that in sas?
You really don't want to rename your variables. You may think you do, but it'll just bite you eventually.
What you can do instead is give them descriptive labels. This can be done via proc datasets.
proc datasets library=<lib>;
modify <dataset>;
label <variable> '5/2/2013 sales';
run;
Just for fun lets assume you want to do this anyway -- Safest thing to do is just create a copy of the dataset for your output...
this code assumes your variable names are named like w1_sales and output names are going to be renamed to 03JAN2013_sale or something like that.
data newDataSet;
set oldDataSet;
%MACRO rename_vars(mdataset,year);
data &mdataset.;
set &mdataset.;
%do i = 1 %to 53;
%let weekStartDate = %sysfunc(intnx('week&i','01jan&year.'d,0)); %*returns the starting day of week(i) uses sunday as starting date. If you want monday use 0.1 as last param;
%let weekstartDateFormatted = %sysfunc(putn(&weekStartDate.,DATE.)) %*formats into ddMONyyy. substitute whatever format you want;
rename w&i._Sale = &weekstartDateFormatted ._SALES;
%end;
run;
%MEND rename_vars;
%rename_vars(newDataSet,2013);
I don't have time to test this right now, so sommebody let me know if I screwed it up somewhere. This should at least get you going though. Or you can send me or post some code to read a small sample dataset (obviously if this is possible without having to share some proprietary info. You might have to genericize it a bit) with those vars like that and I'll debug it.