BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Haikuo
Onyx | Level 15

A short while ago, some one asked how to reset the count every time there is a 'N'. So I was thinking if I can reset it every time if there is a CAPITAL character, it turned out not hard to do, as I am going to show you below. However, what I thought would-be equavalent expression seems not equavalent, one working, one not:

Working solution:

data have;

input var1$;

cards;

a

b

c

N

q

r

a

S

e

N

;

data want (drop=v);

do ct=1 by 1  until (v);

   set have;

    v=missing(compress(var1,,'u'));

   output;

end;

run;

After I switch the contents of 'v' into until(), SAS tells me:

ERROR: Variable var1 has been defined as both character and numeric.

 

data want;

do ct=1 by 1  until (missing(compress(var1,,'u')));

   set have;

   output;

end;

run;

Please shed some light on this one and educate me.

Thanks in advance!

Haikuo

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

My view is that SAS is actually compiling the data step code.  So the first time the COMPILER sees the variable it makes a determination on what type and length to give.  Execution order does not matter.

Some times it is obvious.  A LENGTH or ATTRIB statement or a reference to an existing dataset in the SET statement.

Next level of easy are simple assignment or comparisons.  Your last example is easy for SAS.  It sees that you are testing if VAR1 is equal to a character string so VAR1 gets defined as character. The length of the comparison string is known so VAR1 is length 1.

If SAS can't figure it out it defaults to numeric.

Apparently SAS cannot tell that a variable referenced as the first argument to COMPRESS() function should be a string.  So it gets defined as a number which conflicts with the definition in the dataset referenced later in the SAS statement.

View solution in original post

6 REPLIES 6
art297
Opal | Level 21

If it makes you feel any better, I don't have any idea why it would behave that way either.  My vote is that it is a bug!

Tom
Super User Tom
Super User

Most likely cause is that in the second step the first reference to VAR1 is in the UNTIL() clause. In the first one the first reference is the SET statement.

I am not sure why SAS assumes var1 is numeric if the first reference to it is in a COMPRESS() function.  You would think that would imply a character variable.

Haikuo
Onyx | Level 15

Tom,

I would usually agree with you without even blink. But today you have two more questions of mine:

1. Do until() will not be evaluated until the end of the loop, so why does it matter?

2. And please look below, var1 is character and the first encounter happens in until()?

data have;

input var1$;

cards;

a

b

c

N

q

r

a

S

e

N

;

data want ;

do ct=1 by 1  until (var1='N');

   set have;

   output;

end;

run;

proc print;run;

Thanks,

Haikuo

Tom
Super User Tom
Super User

My view is that SAS is actually compiling the data step code.  So the first time the COMPILER sees the variable it makes a determination on what type and length to give.  Execution order does not matter.

Some times it is obvious.  A LENGTH or ATTRIB statement or a reference to an existing dataset in the SET statement.

Next level of easy are simple assignment or comparisons.  Your last example is easy for SAS.  It sees that you are testing if VAR1 is equal to a character string so VAR1 gets defined as character. The length of the comparison string is known so VAR1 is length 1.

If SAS can't figure it out it defaults to numeric.

Apparently SAS cannot tell that a variable referenced as the first argument to COMPRESS() function should be a string.  So it gets defined as a number which conflicts with the definition in the dataset referenced later in the SAS statement.

Haikuo
Onyx | Level 15

LOL. Art, your answer does make me feel better, that is why it is helpful!

art297
Opal | Level 21

Tom is correct, but I still think it is a bug!  You can get around it by pre-informing SAS that it really is a character variable.  e.g.:

data want;

  length var1 $1;

  do ct=1 by 1  until (missing(compress(var1,,'u')));

    set have;

    output;

  end;

run;

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 1441 views
  • 6 likes
  • 3 in conversation