BookmarkSubscribeRSS Feed
Fisher
Quartz | Level 8

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.

9 REPLIES 9
ballardw
Super User

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.


Fisher
Quartz | Level 8

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

Fugue
Quartz | Level 8

Workaround that should do the trick . . .

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

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

data _null_; 

  j = countw("&unqlst"); 

  put j=;

run;

Tom
Super User Tom
Super User

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

Fisher
Quartz | Level 8

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.

data_null__
Jade | Level 19

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.

Haikuo
Onyx | Level 15

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

Tom
Super User Tom
Super User

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

Fisher
Quartz | Level 8

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.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 2408 views
  • 2 likes
  • 6 in conversation