BookmarkSubscribeRSS Feed
John1231
Fluorite | Level 6

hi,

 

I have a library let's say 'library1'.

 

In this library i have datasets with  the same variables (names, type, etc.) Every dataset is created at the end of the month, so i have for example 

 

dataset_201701

dataset_201702

dataset_201703

 

and so on.

 

Now, datasets have the same variables, but they could have have different lenghts of observations which can cause unexpected results while combining them.

 

Example:

 

dataset_201701 has an observation in variable 'abc' which has lenght of 50 . 

dataset_201702 has an observation in variable 'abc' which has lenght of 40.

 

if someone combines these datasets 

 

data combine;

set dataset_201701 dataset_201702;

run;

 

It will truncate the variable abc to 40.

 

So the question is: How can I check the longest observation in every variable, in every dataset in my library 'library1' and set the lenght for the longest observation ?

 

Basing on my example I want the variable abc to have lenght of 50 in every dataset.

6 REPLIES 6
Reeza
Super User

Get the lengths from SASHELP.VCOLUMN and isolate the maximum values. Then create a LENGTH statement from those values, 

 

Proc sql;
Create table length as
Select name, max(length) as max_length 
From SASHELP.volumns where libname='LIBRARY1'
Group name;
quit;

 

Shmuel
Garnet | Level 18

You can use  - proc sql; select distionary.columns ... - or - sashelp.vcolomn 

in order to create a LENGTH statement with max length of char variables.

 

For example:

proc sort data= sashelp.vcolumn (where=(libname='LIBRARY1' and 
                         substr(memname(1,7) = 'DATASET' and type='char' ))
               out=char_vars; by name descending length;
run;

data _null_;
  set char_vars end=eof;
   by name;
        length len_stmt $100;  /* addapt to max length needed */
        retain len_stmt  'length ';

       if eof then call symput('len', trim(len_stmt));

        if first.name;
        len_stmt = catx(' ',len_stmt, strip(varnmae) , strip(length));
run;

data want;
     &len.;   /* line was editted to eliminate double LENGTH keyword */
 set dataset_201701  dataset_201702 ... ;
run;

 

John1231
Fluorite | Level 6

hey, thank you for your answers but it in not quite what i'm looking for...

 

the main task is to

1 check the longest observation in every data set for each variable

2 change the length for each variable in whole library to the length of the longest variable.

 

and i want to do this each time a new dataset is created (every month), not during combination of sets.

 

example

 

dataset 01

variable abc is 30

dataset 02

variable abc is 40

 

and after running my code the result that i want is:

 

dataset 01

variable abc is 40

dataset 02 

variable abc is 40

Shmuel
Garnet | Level 18

To your suggestion - " check the longest observation in every data" - I have some remarks:

- you possibly use OPTION COMPRESS=YES (check by running: proc options) - then observation lebgth is not symptomatic.

- if there are more severeal char variables in a dataset, you cannot conclude which variable to expand.

 

sashelp.vcolumn - holds information on all members (datasets) in all libraries, so there is no need to check each dataset.

Taking max(length) as suggested by @Reeza or taking the first length when sorted by descending - you shall get the same result.

 

The code I posted relates to your selected library (library1), checks all datasets named with prefix DATASET (names you gave).

The variable NAME is the variable name in the dataset.

I create a macro variable containing the LENGTH statement to use with maximun length of all character variables in those

selected datasets. Finally  I show hot to use this macro variable.

 

You can use it any time you need to concatenate datasets OR you can use it to convert your datasets to be all with same

definitions of maximum length. Using OPTION COMPRESS=YES will compress data so that you save disk space inspite

expanding length of variables.

 

In order to convert your dataset to standard max length run:

     data library1.dataset_<any month>;

         &len;

       set  library1.dataset_<any month>; 

     RUN;

Reeza
Super User

Then what you should actually do, is define your process better with fixed lengths for your values. You should know what the maximums will be and create a table as that structure. Then insert the records into that table. 

 

The solutions provided, scan all tables and take the longest length assigned. This is in line with how your question is posed. Actually scanning each record every time is inefficient. It's better to understand your data and make the limits based on your knowledge of the process rather than building it based on what you see in the data currently. 

Patrick
Opal | Level 21

@John1231

As @Reeza already wrote: You should know your data and define the variable attributes upfront. Analyzing and changing the data every single time sounds like a bad idea.

If your problem is that you're creating monthly data with different variable lengths then combining the data using a PROC SQL UNION will pre-analyse your variable definitions and will take the longest length (=no truncation risk).

proc sql;
  create table all_months as
    select *
    from dataset_201701
    outer union corr
    select *
    from dataset_201702
   ;
quit;

 

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
  • 6 replies
  • 3343 views
  • 1 like
  • 4 in conversation