Hi,
I have problem with this simple code:
%let lst= "1234" "3222" "0056";
data _null_;
j = countw("&lst");
put j=;
run;
I expect to get how many quoted strings in the list, but this code creates error:
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.
How to fix it? thanks in advance.
If the issue is counting words you don't even need a data set.
%put %sysfunc(countw(&lst,' ')) ;
Within the data step you want:
countw(&lst)
since you provided your quotes in the intial assignment. If you hadn't then you would want the "&lst" syntax.
Thanks. In data step, countw(&lst) does not work, which I really don't understand.
Workaround that should do the trick . . .
%let lst= "1234" "3222" "0056";
%let unqlst = %sysfunc(compress("&lst", '"'));
data _null_;
j = countw("&unqlst");
put j=;
run;
18 %let lst= "1234" "3222" "0056";
19
20 data _null_;
21 j = countw(symget('lst'));
22 put j=;
23 run;
j=3
NOTE: DATA statement used (Total process time):
24
25 %let j=%sysfunc(countw(&lst));
26 %put j=&j ;
j=3
Thanks Tom. This is interesting. Can you explain why countw(symget('lst')) works while countw("&lst") does not? To my knowledge, symget() retrieves the macro value during the run time, while, in countw("&lst"), &lst is resolved during the compile time and the macro variable value is returned to countw().
thanks again.
Look up in the documentation the syntax for a double quoted string that includes double quotes in its value.
You would have to double the double quotes.
Also see the QUOTE function.
Like DN hinted in his reply, this fiasco is the result of DOUBLE quote, and it is irrelevant to compile or run time. "&lst" resolves to ""1234" "3222" "0056"", and SAS is confused on which double quote is the part of your string, and which one is the wrapper. In the case of normal string, you can wrap it with a SINGLE quote, then SAS will behave the way that you are expecting:
data _null_;
j = countw('"1234" "3222" "0056"');
put j=;
run;
For Macro variables, you have some choices to make in order to resolve a macro variable and define the boundary at the same time,
1. The most used option: DOUBLE quote.
2. symget() or resolve()
Option 1 does not work, so that leave you with the option 2.
Of course, if you choose single quote to start with, we don't even have to have this discussion:
%let lst= '1234' '3222' '0056';
data _null_;
j = countw("&lst");
put j=;
run;
HTH,
Haikuo
When you resolve a macro variable (&LST) the value is expanded and the resulting string of characters is passed on as if you had typed them into your program. In normal SAS code you need to distinguish between variables and literal strings. You can do this with either single or double quotes to "wrap" the literal string. If you need to include a version of the quote character you are using o wrap your string then you double it up. ('don''t') The problem with your attempt is that the generated code is invalid SAS syntax.
Using SYMGET() avoids the quoting issue since it is not using a string literal (well it is but the string is name of the macro variable to get) and is instead passing the result of the SYMGET() function to the COUNTW() function.
There are other solutions.
1) Use single quotes in the macro variable so that "&lst" does not generated unbalanced quotes.
2) Use the QUOTE() function via %SYSFUNC() macro function to double up the internal quotes and make it a valid string literal. Example: countw(%sysfunc(quote(&lst)))
3) And probably the best solution is to not put the quotes into the macro variable to begin with. Why are they there anyway? If you thought they would "protect" embedded spaces then you need to use the Q modifier on the COUNTW() function. Example: countw(symget('lst'),' ','Q')
Thanks Tom and all other contributors, these discussions and sharings are very meaningful and clarify some concept in my mind.
I think we can close this discussions now.
Thanks again, everyone.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Early bird rate extended! Save $200 when you sign up by March 31.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.