BookmarkSubscribeRSS Feed
noda6003
Quartz | Level 8

How to resize sas datasets.

I found a program in sas but it gives errors. one of the error is 

http://support.sas.com/resources/papers/proceedings13/206P-2013.pdf

 

ERROR: File WORK.MAXX_T.DATA does not exist.

 

May be i am missing something.  Any one knows program which does the resizing. please let me know

 

%macro chglen (inp=sl);

	proc contents data = &inp. noprint
		out = charvar (where =(type=2)
		keep = memname name type length label);
	run;

	data charvar2;
		length name1 name2 name3 name4 name5 $100;
		set charvar;
		name1 = trim(name)||'1=length('||trim(name)||')';
		name2 = 'max('||trim(name)||'1) as '||trim(name);
		name3 = trim(name)||'x = '||trim(name);
		name4 = trim(name)||' = '||trim(name)||'x';
		name5 = trim(name)||' $'||strip(put(length, best.));
	run;

	proc sql noprint;
		select trim(name1) into: newvar separated by '; '
			from charvar2;
		select trim(name2) into: maxvar separated by ', '
			from charvar2;
		select trim(name3) into: tname separated by '; '
			from charvar2;
		select trim(name4) into: tnamex separated by '; '
			from charvar2;
		select trim(name) into: cvar separated by ' '
			from charvar2;
		select trim(name)||'x' into: cvarx separated by ' '
			from charvar2;
		select trim(name5) into: cvarlen separated by ' '
			from charvar2;
	quit;

	data varlen;
		set &inp.;
		&newvar;
	run;

	proc sql noprint;
		create table maxx as
			select &maxvar
				from varlen;
	quit;

	data maxx_t2;
		length name6 $100;
		set maxx_t;

		if col1<1 then
			col1=1;
		name6 = trim(name)||' $'||strip(put(col1, best.));
	run;

	proc sql noprint;
		select strip(name6) into: newlen separated by ' '
			from maxx_t2;
	quit;

	data temp (drop = &cvar. );
		length &cvarlen;
		set &inp.;
		&tname.;
	run;

	data newone (drop= &cvarx.);
		length &newlen.;
		set temp;
		&tnamex.;
	run;

%mend chglen;

%chglen;
7 REPLIES 7
gamotte
Rhodochrosite | Level 12

Hello,

 

The message in the log is quite clear : you refer to a dataset MAXX_T which doesn't exist.

 

The problem occurs in the data step that creates maxx_t2 :

 

data maxx_t2;
		length name6 $100;
		set maxx_t; /* HERE ! */
...
run;

The preceeding proc sql cretaes a dataset named MAXX. Maybe it is a typo and it should be named MAXX_T.

noda6003
Quartz | Level 8

It still gives errors

 

NOTE: Line generated by the macro variable "NEWLEN".
1 . $1
-
22
200

ERROR 22-322: Syntax error, expecting one of the following: a name, ;, DEFAULT, _ALL_, _CHARACTER_, _CHAR_, _NUMERIC_.

ERROR 200-322: The symbol is not recognized and will be ignored.

NOTE: The SAS System stopped processing this step because of errors.

gamotte
Rhodochrosite | Level 12

This program seems overly complicated and i can't really figure out what it does by just reading it.

 

If the goal is just to modify the length of character columns to the minimal length that avoids truncation,

you can try the following macro :

 

%macro resize(lib=sashelp, mem=class, out=&mem.);

    proc sql noprint;
        /* We get the list of charcter columns */
        SELECT NAME
        INTO :CHARCOLS SEPARATED BY ' '
        FROM dictionary.columns
        WHERE LIBNAME=upcase("&lib.") AND MEMNAME=upcase("&mem.")
        AND upcase(TYPE)="CHAR";

        /* For each char column we get the minimum length that avoids truncation */
        /* Ex: "var1 $5. var2 $7. ..."                                           */
        %let nchars=%sysfunc(countw(&CHARCOLS));

        SELECT DISTINCT cat(
        %do i=1 %to &nchars.;
            %let col=%scan(&CHARCOLS.,&i.,' ');
            " &col. $",max(length(&col.)),".",
        %end;
        "") /* "" for the last comma */
        INTO :lengths SEPARATED BY ' '
        FROM &lib..&mem.;
    quit;

    /* New dataset with resized char columns */
    data &out.;
        length &lengths.;
        set &lib..&mem.;

    run;

%mend resize;

%resize;

SASKiwi
PROC Star

What is the purpose of resizing your SAS datasets? If it is just to save space then it is a whole lot easier to use the SAS option COMPRESS = YES or COMPRESS = BINARY. We have the compression option set permanently to BINARY on our SAS installations and it works extremely well. 

DaveHorne
SAS Employee

I've had good results using the %chg_length macro documented in the sample library: http://support.sas.com/kb/48/638.html

I use it most often when extracting data from a third party database.  It can make a huge performance benefit when you don't need to drag around large character variables.

ballardw
Super User

What do you actually mean by "resize"?

 

You may want to consider learning to use the various CAT functions instead of the || operator. You can avoid most of the Trim() calls using CATS:

data charvar2;
   length name1 name2 name3 name4 name5 $100;
   set charvar;
   name1 = cats(name),'1=length(',name),')');
   name2 = cats('max(',name,'1) as ',name);
name5 = cats('name,' $',length);
run;

CATS, CATT , CATX, CATQ and CAT all will automatically use the best. format to convert numeric values.

 

 

 

 

ErikLund_Jensen
Rhodochrosite | Level 12

Hi @noda6003 

 

Long character variables has always been a problem i SAS, and setting new lengths based on an analysis of actual data is dangerous, because next day's actual data might be longer. Some variables have content with a defined max. length, like a postal code or social security number, and for these the length can be set safely.

 

But give ample space to varying-length text, e.g. use 200 if actual data says 157. Consider compressing your SAS data with compress=char, if your concern is disk space.

 

An easy way to find the lengths in actual data is to export the troublesome variables to csv and import them to a work data set:

 

data have;
	length name1 name2 name3 $1024;
	name1 = 'Tom'; name2 = 'W.'; name3 = 'Jones';
run;

filename csvfile "%sysfunc(getoption(work))\w.csv";
proc export data=have outfile=csvfile dbms=csv replace;
run;
proc import datafile=csvfile out=want dbms=csv replace;
run;

 

lengths.gif

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 7 replies
  • 2000 views
  • 0 likes
  • 6 in conversation