BookmarkSubscribeRSS Feed
PGStats
Opal | Level 21

I'm sure there would be plenty of uses for syntax like :

data B;

set A(keep=myLine);

infile _infile_=myLine;

input ... ;

run;

I don't like using code that is heavily dependent on side-effects for any serious work. Syntax like above would be simpler to code and much easier to read and understand.

PG

PG
Peter_C
Rhodochrosite | Level 12

Art

thank you for providing the solution to my (this time unintentional) error!

I was offering such a basic approach because I see absolutely no reason to make that kind of conversion (num--> char) into a table/dataset. And the original poster offered no context where such a data handling model might be useful or needed by an application. So I thought since data type was to be stripped back to simple text, I thought it might be even more convenient to deliver a collection of these numerics. - and it opens the discussion up, beyond the dictionary tables

Often I adapt the community.org apprach with a : instead of the +0

(it pre-dates community)

Had it appeared useful, I might have introduced a DLM= or better still, DSD on a suitable file statement.

When it comes to re-loading original lengths, despair!   Why not just keep numerics numeric?

Can you imagine a context where this conversion helps anything except a homework?

Linlin
Lapis Lazuli | Level 10

example (red part must be upcase):

data have;

  input id $ sex $ a b c d e ;

  cards;

1 2 11 22 33 44 55

  ;

proc sql noprint;

select catx(' ','put(',name,',8.) as',name) into : list1 separated by ','

  from dictionary.columns

   where libname='WORK' and memname='HAVE' and type ='num' ;

select name into : list2 separated by ','

  from dictionary.columns

   where libname='WORK' and memname='HAVE' and type ='char' ;

create table want as

  select &list1,&list2  from have;

quit;

proc contents data=want;run;

oht
Calcite | Level 5 oht
Calcite | Level 5

Hi LinLin,

Your code works out very good. The only problem I have is the final dataset WANT has all the variables $200. Is there any way for the char variable to maintain their original format length  ?

Thanks

Linlin
Lapis Lazuli | Level 10

Hi,

I don't know how to maintain the original length. You can assign a fixed length to all the variables.

data have;

  input id $ sex $ a b c d e ;

  cards;

1 2 11 22 33 44 55

  ;

proc sql noprint;

select cat('put(',strip(name),',8.) as ',strip(name), ' length=20') into : list1 separated by ','

  from dictionary.columns

   where libname='WORK' and memname='HAVE' and type ='num' ;

select name into : list2 separated by ','

  from dictionary.columns

   where libname='WORK' and memname='HAVE' and type ='char' ;

create table want as

  select &list1,&list2  from have;

quit;

proc contents data=want;run;

                           #    Variable    Type    Len

                           1    a           Char     20

                           2    b           Char     20

                           3    c           Char     20

                           4    d           Char     20

                           5    e           Char     20

                           6    id          Char      8

                           7    sex         Char      8

oht
Calcite | Level 5 oht
Calcite | Level 5

Hi LinLin,

I find some other tedious way of getting back the original attr. It works.

Thanks for all your help.


ArtC
Rhodochrosite | Level 12

The following macro, which I found in Appendix 1 a macro book**, does the conversion that  you are looking for.  It has the advantage of maintaining variable names and labels and uses any numeric formats (such as dates) in the conversion.

**********************;
***A1.6.4
***%ALLCHAR
**********************;
%macro allchar(dsn);
* Determine the numeric vars in &dsn;
proc contents data=&dsn out=cont noprint;
run;

* Create the macro variables for each numeric var;
data _null_;;
set cont(keep=name type format formatl formatd label);
length fmt $15;
where  type=1;

* Count the numeric vars and save the total number;
i+1;
ii=left(put(i,3.));
call symput('n',ii);

* create a format string;
fmt = 'best.';
if format ne ' ' then fmt = trim(format)
    ||trim(left(put(formatl,3.)))
    ||'.'||left(put(formatd,3.));
fmt = compress(fmt);
call symput('fmt'||ii,fmt);

* Save the variable name;
call symput('name'||ii,name);

* Save the label for this variable;
if label = ' ' then label = name;
call symput('label'||ii,label);
run;

* Establish a data set with only character variables;
* &n       number of numeric variables in &dsn;
* __aa&i   temporary var to hold numeric values;
* &&name&i name of the variable to covert from numeric;
*
* The numeric value of &name1 is stored in __aa1
* by renaming the variable in the SET statement.  __aa1
* is then converted to character and stored in the
* 'new' variable &name1 in the data set CHARONLY.
* ;
data charonly (drop=
   %* Drop the temp. vars used to hold numeric values;
   %do i=1 %to &n;
      __aa&i
   %end;
    );
length
   %* Establish the vars as character;
   %do i=1 %to &n;
      &&name&i
   %end;
    $8;

set &dsn (rename=(
   %* Rename the incoming numeric var to a temp name;
   %* This allows the reuse of the variables name;
   %do i=1 %to &n;
      &&name&i=__aa&i
   %end;
   ));

   * Convert the numeric values to character;
   %do i=1 %to &n;
      &&name&i = left(put(__aa&i,&&fmt&i));
      label &&name&i = "&&label&i";
   %end;
run;

proc contents data=charonly;
proc print data=charonly;
run;
%mend allchar;

%allchar(sasclass.biomass)

** Appendix 1 of Carpenter's Complete Guide to the SAS Macro Language, 2nd Edition.  Used with the permission of the author.Smiley Wink

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 21 replies
  • 2647 views
  • 4 likes
  • 9 in conversation