SAS Function COUNTW - how to count word including NULL value when using customised delimiter? - sas

Trying to use the function COUNTW to get the number of "words" within a string.
But this string may sometimes contain NULL value when it is comma delimited;
I found some custom macro that can do that, just wondering if I can achieve the same with in-built function, COUNTW for example.
For example:
%put %wordcount('abc, , ,def,,56j,type',DLM=%str(,));
The above is a custom function, and it returns 7
%put %sysfunc(countw('abc, , ,def,,56j,type',%str(,)));
COUNTW returns 6 because it does not counting the NULL between 2 commas (",,")

Very simple, just look at the online documentation! COUNTW has optional modifiers, one of which is M which tells the function to include consecutive delimiters as a word, not null.
The following code returns 7, not 6.
%put %sysfunc(countw('abc, , ,def,,56j,type',%str(,),M));

Related

custom substr function in Oracle

I would like to build a custom function with 3 parameters ,something like Oracle's substr function.
I want to use it to extract a value between a delimiter e.g. semicolon from a large text
the input parameter should be a blob data type to be able use large text.
then the 2nd and 3th parameter should define the occurrence of the delimiter
example
text= ; abc1 ; abc2 ; abc3 ;
select custom_function( text,2,3) from dual
will give me abc2.
It must be a function and I know I could use regexp_substr which is very easy but there is a limit of max length of the input string.

Can input function take a macro variable as character argument?

SAS says: ERROR: INPUT function requires a character argument.
when I run the following code:
%let fyq0 = 000930 ;
%put &fyq0 ;
proc sql ;
create table check as
select *, input(&fyq0,yymmdd6.) as fyq0
from q ;
quit ;
I tried to have '&fyq0' instead of &fyq0 as the 1st argument for the -input- function as the following:
%let fyq0 = 000930 ;
%put &fyq0 ;
proc sql ;
create table check as
select *, input('&fyq0',yymmdd6.) as fyq0
from q ;
quit ;
Then SAS says: NOTE: Invalid argument to function INPUT. Missing values may be generated. And indeed, variable fyq0 returns a missing value.
I wonder what went wrong with my approaches and what is the correct way to go.
The macro processor just replaces the macro reference with the resolved text and then the generated text is interpreted as text. So when you tried.
input(&fyq0,yymmdd6.)
it was the same as if your code was
input(000930,yymmdd6.)
Even if that did run SAS would first have to convert the number 930 into a character string using the BEST12. format which would result in a string like
' 930'
and the input function would only read 6 of the leading spaces.
The macro processor does not process text inside of single quotes. So the INPUT function could not convert the five character string '&fyq0' to a valid date since the letters and ampersand are not valid digits.
You can use double quote characters to allow SAS to resolve the macro variable reference.
input("&fyq0",yymmdd6.)
Now the macro variable reference will resolve and code generated will be:
input("000930",yymmdd6.)

Length of a SAS macro variable that contains quotes and commas

Let the sample macro variable be
%let temp="A","B","C";
How do you get the array length of this macro variable, which includes quotations and commas? For example, I would want to return length 3.
%let length_of_temp=%sysfunc(SOME_FUNC(&temp.));
%put length=length_of_temp;
LOG: length=3
Preferably I would want to do it using one established SAS function or line of code, not creating a new function for processing. Here is what I have attempted so far:
countw("&temp.",","): the quotes create an error when trying to convert it to a string.
NOTE: Line generated by the macro variable "TEMP". 4
""A","B","C"
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS
release. Inserting white space between a quoted string and the succeeding
identifier is recommended.
ERROR 388-185: Expecting an arithmetic operator.
countw(&temp.,",") and count(&temp.): typical error of function call has too many arguments
count((&temp.)) and dim((&temp.))
variations using %superq on the above
Use macro quoting on your macro variable value so that commas do not cause trouble for call to countw() function. Use the q and possibly the m optional third argument to the countw() function to let it know not to count delimiters that are inside the quotes.
%let temp="A1,a2","B","C";
%let count = %sysfunc(countw(%superq(temp),%str(,),mq));
If you want to calculate the count in a data step then instead of macro quoting you can use the symget() function to retrieve the value of the macro variable.
count = countw(symget('temp'),',','mq');
THis works for me:
%let temp="A","B","C";
%let count = %sysfunc(countw("&temp", ","));
%put Number of elements = &count.;
Results:
8002 %put Number of elements = &count.;
Number of elements = 3
The %quote function might be helpful here to mask the quotation marks:
%let count = %sysfunc(countw(%quote(&temp), ","));
%put Number of elements = &count.;

SAS search and replace the last word using regex [duplicate]

Match strings ending in certain character
I am trying to get create a new variable which indicates if a string ends with a certain character.
Below is what I have tried, but when this code is run, the variable ending_in_e is all zeros. I would expect that names like "Alice" and "Jane" would be matched by the code below, but they are not:
proc sql;
select *,
case
when prxmatch("/e$/",name) then 1
else 0
end as ending_in_e
from sashelp.class
;quit;
You should account for the fact that, in SAS, strings are of char type and spaces are added up to the string end if the actual value is shorter than the buffer.
Either trim the string:
prxmatch("/e$/",trim(name))
Or add a whitespace pattern:
prxmatch("/e\s*$/",name)
^^^
to match 0 or more whitespaces.
SAS character variables are fixed length. So you either need to trim the trailing spaces or include them in your regular expression.
Regular expressions are powerful, but they might be confusing to some. For such a simple pattern it might be clearer to use simpler functions.
proc print data=sashelp.class ;
where char(name,length(name))='e';
run;

Append extra characters after a macro variable in SAS?

I have a simple macro where I am passing in a parameter but also want to append onto the macro. However, when I try to add the additional text it won't recognize the original macro variable. I have tried to convert the macro variable to a string first, append the extra text, then unquote it but can't find an appropriate concatenate function to use.
Here is my macro and what isn't working now, with the problem being &del_30 in the third line. The compiler is trying to interpret &del_30 as a macro, instead of &del_ by itself.
%macro plot_better_same_worse(title_, del_);
proc Sgplot data=ALL_TP_NORM_TBL;
SERIES X = asofdt Y = &del_30 /
MARKERS LINEATTRS = (THICKNESS = 2);
run;
%mend plot_better_same_worse;
I have also tried to do this instead: &&del_&30 but SAS tries to interpret &30 as a macro variable as well.
Macro variable names begin with & and end with ., or the first character illegal to be in a macro variable name (A-Z, 0-9, _).
So &del_.30 would resolve &del_ and then put 30 after it.