Hi, I am learning SAS in online SAS studio as a R user following "sas-programming-for-r-users". I got the problem to use self-defined function in the exercise of the book: P69
data work.cars1;
set sashelp.cars;
mpg_average = mean(mpg_city,mpg_highway);
run;
proc fcmp outlib=work.functions.newfuncs;
function Tier(mpg_average) $;
length mpg_quality2 $ 8;
if mpg_average < 20 then mpg_quality2 = 'Low';
else if mpg_average <30 then mpg_quality2 = 'Median';
else mpg_quality2 = 'High';
return(mpg_quality2);
endsub;
quit;
options cmplib=work.functions;
data work.cars1;
set work.cars1;
length mpg_quality2 $ 8;
mpg_quality2 = Tier(mpg_average);
run;proc print data=work.cars1 (firstobs=65 obs=70);
var mpg_average mpg_quality mpg_quality2;
run;
I could not add variable mpg_quality2 since
"ERROR 68-185: The function TIER is unknown, or cannot be accessed."
Why proc fcmp does not work?
Thanks!
You would have to show the LOG for your FCMP code to see why it may not work. Does your log show text similar to this after Proc FCMP ?
NOTE: Function Tier saved to work.functions.newfuncs. NOTE: PROCEDURE FCMP used (Total process time): real time 0.05 seconds cpu time 0.03 seconds
When I use your function with a small data set compiled locally it runs okay.
I did see a character between the end of Proc FCMP and the Options statement that SAS didn't like so check your log. If there are more that made it into your code that could be an issue. Also, it is a good idea to paste code or log text into a text box opened on the forum with the </> that appears above the message window. The main message windows on the forum will reformat text, especially white space characters, and may result in code that doesn't run.
What your function is doing is more typically done with a custom FORMAT in SAS than a function. Formats are look ups but restricted to single variable/ value
Proc format; value mpg_tier low - <20 = 'Low' 20 - < 30 = 'Median' 30 - High = 'High' ; run; /* use without creating new variable*/ Proc print data=work.cars1; var mpg_average; format mpg_average mpg_tier. ; run; /* or create a new variable with PUT function and the format*/ data work.cars2; set work.cars1; mpg_quality2 = put(mpg_average, mpg_tier.); run;
There are very limited transforms that could be done with Format code. A function would be more appropriate for something using 2 or more variables or a more complex calculation or changing calculation based on range of values.
Thanks a lot!
My log file is actually problematic:
NOTE: PROCEDURE FCMP used (Total process time):real time 2:30.68user cpu time 0.04 secondssystem cpu time 0.02 secondsmemory 5713.87kOS Memory 29608.00kTimestamp 12/05/2022 11:54:36 PMStep Count 25 Switch Count 5Page Faults 0Page Reclaims 651Page Swaps 0Voluntary Context Switches 1407Involuntary Context Switches 0Block Input Operations 0Block Output Operations 81 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;ERROR: At least one file associated with fileref _HTMLOUT is still in use.ERROR: Error in the FILENAME statement.6869 data work.cars1;70 set sashelp.cars;71 mpg_average = mean(mpg_city,mpg_highway);72 run;NOTE: There were 428 observations read from the data set SASHELP.CARS.NOTE: The data set WORK.CARS1 has 428 observations and 16 variables.NOTE: DATA statement used (Total process time):real time 0.00 secondsuser cpu time 0.00 secondssystem cpu time 0.00 secondsmemory 836.90kOS Memory 24996.00kTimestamp 12/05/2022 11:54:36 PMStep Count 30 Switch Count 2Page Faults 0Page Reclaims 109Page Swaps 0Voluntary Context Switches 9Involuntary Context Switches 0Block Input Operations 0Block Output Operations 2647374 proc fcmp outlib=work.functions.newfuncs;
proc fcmp outlib=work.functions.newfuncs;
Save the code, restart the session and run the code in a clean session.
The errors about statements not shown, i.e. Filename, is problematic since it would be very session dependent.
Code not completing may be an issue of how you submit it, if submitting "highlighted lines" or similar, or maybe having code in a comment that is not properly ended. Use of macro characters & or % somewhere may also be problematic.
BTW, while learning SAS it is generally not a good idea to use the same data set as source (set statement) and output (data statement) as data steps completely replace a data set when using that structure. So a minor logic error may mean having to go back (some times many) step to recover data that has been removed or modified.
So instead of
data work.cars1; set work.cars1; <other code>
It is better to use
data work.cars2; set work.cars1; <other code>
Your example isn't too complicated but it can be a real bear to find out "where did that value come from" sometimes when you have replaced the source set.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.