BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Aidaan_10
Calcite | Level 5

Hi,

                 I am trying to round multiple variables from below dataset B. Dataset A is my reference dataset with rounding requirements for decimal places. Below in this dummy data I have less number of variables but in real data there are many variables, the following code works as expected for less variables but for lot of variables I am getting the below error:

ERROR: The length of the value of the macro variable LGT_MACRO (65540) exceeds the maximum length (65534). The value has been
truncated to 65534 characters.

Can someone please help me fixing  the above error.

 

Example  datasets are below

/*Dataset A:*/
/*If not an integer then round to number of decimal places from Var1 column*/

data a;
informat var1 $50. length $10. var2 $200.;
infile datalines delimiter=',';
input var1 length var2 ;

datalines;
NotAvailable,8,Subject
NotAvailable,8,Site
NotAvailable,$200,Visit
integer,8,Age
0.0001,8,Score1
integer,8,Score2
NotAvailable,$200,Date
0.00001,8,Score_3
NotAvailable,$200,I_am_the_longest_variable_Test_3
;
run;

 

/*dataset B:*/
data b;
informat Visit $200. Date $200. I_am_the_longest_variable_Test_3 $200.;
infile datalines delimiter=',';
input Subject Site Visit Age Score1 Score2 Date Score_3 I_am_the_longest_variable_Test_3 ;

datalines;
1234,001,Day1,55,344.70452025162167,4,2023-06-08 15:37,4.5707963267948966,ABCD
2456,002,Day5,45,100.12342025162167,3,2023-06-09 15:37,3.1234907586284892,WXYZ
3456,003,Day1,60,94.38627492995121,2,2023-06-10 15:37,5.7398282916662683,ABCD
7890,001,Day5,52,92.28219778353588,1,2023-06-08 15:37,3.749207747474,WXYZ
1111,002,Day1,70,124.6789456782671,3,2023-06-09 15:37,4.172819191919191,ABCD
1567,003,Day1,59,125.4796290763492,5,2023-06-10 15:37,1.272383939999,WXYZ
;
run;


data a1;
set a;
if index(length,'$')>0 or UPCASE(var1)='NOTAVAILABLE' then ;
else if UPCASE(var1)='INTEGER' then Rnd_var=0;
else If UPCASE(var1)='0.0001' then Rnd_var=0.0001;
else If UPCASE(var1)='0.00001' then Rnd_var=0.00001;
else If UPCASE(var1)='NOTAVAILABLE' then Rnd_var=.;
run;

 

data sample_formats;
set a1;
format length_macr0 $100. ;
if index(length,'$')> 0 or UPCASE(var1) in ('NOTAVAILABLE') then length_macr0='';
else length_macr0=cat(compress(var2),'=','round(',compress(var2),',',compress(rnd_var),')') ;
run;


proc sql;
select length_macr0 into :lgt_macro separated by ";"
from sample_formats
where length_macr0 is not missing
;
%put length_macr0;

data test;
set b;
&lgt_macro. ;
run;

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

If the goal is to generate CODE from the metadata in the dataset A then it might be easier to do that by just writing the code directly from the dataset and skipping the macro variable.

 

filename code temp;
data _null_;
  file code ;
  set a;
  where not (index(length,'$') or upcase(var1)='NOTAVAILABLE');
  if upcase(var1)='INTEGER' then var1=1;
  put var2 '=round(' var2 ',' var1 ');' ;
run;

data test;
  set b;
%include code / source2 ;
run;
1940  data test;
1941    set b;
1942  %include code / source2 ;
NOTE: %INCLUDE (level 1) file CODE is (system-specific pathname).
1943 +Age =round(Age ,1 );
1944 +Score1 =round(Score1 ,0.0001 );
1945 +Score2 =round(Score2 ,1 );
1946 +Score_3 =round(Score_3 ,0.00001 );
NOTE: %INCLUDE (level 1) ending.
1947  run;

NOTE: The data set WORK.TEST has 6 observations and 9 variables.

 

PS You seem to be trying to use INFORMAT and FORMAT as if they were designed to DEFINE variables.  That is not what those statements are for. The only reason they work in your code is because it is the first place the variable is mentioned so the data step compiler is forced to GUESS that you wanted the LENGTH of the variable to be defined to match the WIDTH of the informat or format that you wanted to attach to it.

View solution in original post

4 REPLIES 4
yabwon
Onyx | Level 15

this part:

 

proc sql;
select length_macr0 into :lgt_macro separated by ";"
from sample_formats
where length_macr0 is not missing
;

causes the problem, the data extracted in the length_macr0 variable is bigger than possible macrovariable length. 

 

you can do 2 things: 

1) make it: select STRIP(length_macr0) into :lgt_macro separated by ";"

or

2) create a macrovariable list: select length_macr0 into :lgt_macro1-

 and when the list is created call to its elements like: &&lgt_macro%i where the "i" is macro %do-loop iterator.

 

Bart

 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Tom
Super User Tom
Super User

If the goal is to generate CODE from the metadata in the dataset A then it might be easier to do that by just writing the code directly from the dataset and skipping the macro variable.

 

filename code temp;
data _null_;
  file code ;
  set a;
  where not (index(length,'$') or upcase(var1)='NOTAVAILABLE');
  if upcase(var1)='INTEGER' then var1=1;
  put var2 '=round(' var2 ',' var1 ');' ;
run;

data test;
  set b;
%include code / source2 ;
run;
1940  data test;
1941    set b;
1942  %include code / source2 ;
NOTE: %INCLUDE (level 1) file CODE is (system-specific pathname).
1943 +Age =round(Age ,1 );
1944 +Score1 =round(Score1 ,0.0001 );
1945 +Score2 =round(Score2 ,1 );
1946 +Score_3 =round(Score_3 ,0.00001 );
NOTE: %INCLUDE (level 1) ending.
1947  run;

NOTE: The data set WORK.TEST has 6 observations and 9 variables.

 

PS You seem to be trying to use INFORMAT and FORMAT as if they were designed to DEFINE variables.  That is not what those statements are for. The only reason they work in your code is because it is the first place the variable is mentioned so the data step compiler is forced to GUESS that you wanted the LENGTH of the variable to be defined to match the WIDTH of the informat or format that you wanted to attach to it.

Aidaan_10
Calcite | Level 5

Thanks Tom...this worked.

ballardw
Super User

More than a little concerned about reading any DATE type value as $200 to begin with. SAS dates should generally be date, time or datetime valued with an appropriate format though the values should be integer unless dealing with fractional seconds.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
SAS Enterprise Guide vs. SAS Studio

What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

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
  • 4 replies
  • 1564 views
  • 0 likes
  • 4 in conversation