DATA Step, Macro, Functions and more

countw() and double quoted string list

Reply
Contributor
Posts: 70

countw() and double quoted string list

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.

Super User
Posts: 10,500

Re: countw() and double quoted string list

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.


Contributor
Posts: 70

Re: countw() and double quoted string list

Thanks. In data step, countw(&lst) does not work, which I really don't understand.

Super Contributor
Posts: 307

Re: countw() and double quoted string list

Workaround that should do the trick . . .

%let lst= "1234" "3222" "0056";

%let unqlst = %sysfunc(compress("&lst", '"'));

data _null_; 

  j = countw("&unqlst"); 

  put j=;

run;

Super User
Super User
Posts: 6,500

Re: countw() and double quoted string list

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

Contributor
Posts: 70

Re: countw() and double quoted string list

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.

Respected Advisor
Posts: 3,777

Re: countw() and double quoted string list

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.

Respected Advisor
Posts: 3,124

Re: countw() and double quoted string list

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

Super User
Super User
Posts: 6,500

Re: countw() and double quoted string list

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')

Contributor
Posts: 70

Re: countw() and double quoted string list

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.

Ask a Question
Discussion stats
  • 9 replies
  • 646 views
  • 2 likes
  • 6 in conversation