LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (August 2006, week 5)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Tue, 29 Aug 2006 17:31:54 -0700
Reply-To:     Ai Hua Wang <aihuawang@YAHOO.COM>
Sender:       "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:         Ai Hua Wang <aihuawang@YAHOO.COM>
Subject:      Re: conversion from num to char in data step
Comments: To: Ed Heaton <EdHeaton@WESTAT.COM>
In-Reply-To:  <403593359CA56C4CAE1F8F4F00DCFE7D056DD16A@MAILBE2.westat.com>
Content-Type: text/plain; charset=iso-8859-1

Hi Ed:

Thank you so much for your code. I will use them in the future for data type conversion. You also provide a new method for reordering the sequence of the variable in the table. I often use PROC Transpose which often involves a long list of variable names in the keep and copy statements.

Take care,

Aihua Wang

Aiuha,

You can't convert a numeric variable to character -- directly. You can, however, convert a numeric value to a character value. So, you can create a character variable to hold the converted numeric value. There exist a slew of associated issues.

Data new( drop=_v1 ) ; Set old( rename=(v1=_v1) ) ; v1 = put( _v1 , 9.-L ) ; Run ;

However, this too has problems. Your new variable will be the last column of your new dataset rather than in the location where you started. To fix this, you need a list of the variables as they exist in the original dataset.

Proc contents data=old out=vars( keep= VarNum Name ) noPrint ; Run ; Proc sql noPrint ; Select Name into :orderedVariables separated by ' ' from vars order by VarNum ; Quit ; Data new( drop=_v1 ) ; Retain &orderedVariables ; Set old( rename=(v1=_v1) ) ; v1 = put( _v1 , 9.-L ) ; Run ;

As you can see, this isn't trivial. However, you can make it trivial with a useful (but untested) macro. Another macro that I wrote -- %CHAR2NUM() -- was copied and adapted to create the following macro.

/*********************************************************************** ******** MACRO: %num2char()

OBJECTIVE: This macro will convert a specified list of numeric variables and their data to character. The major advantages of this macro are 1. it preserves the order of the variables and 2. it allows the user to use standard SAS variable-list notation. This macro was tested under SAS 9.1.3. It will not run on SAS 8.2 or earlier versions.

VALID: between program steps

USAGE: %num2char( data= , out= , numVars= , inFormat= )

PROGRAMMER: Edward Heaton, SAS Senior Systems Analyst, Westat (An Employee-Owned Research Corporation), 1650 Research Boulevard, RW-4541, Rockville, MD 20850-3195 Voice: (301) 610-4818 Fax: (301) 294-3879 mailto:EdHeaton@Westat.com http://www.Westat.com

PARAMETERS: data= specifies the input dataset. (The default is the last data set that was created in this SAS session.) out= specifies the output dataset. (The default is _data_ which will produce a dataset named DATA1 or DATA2 or ...) numVars= specifies the numeric variables that have data that represent numbers. You can use any of the standard methods of listing these variables. (The default is _NUMERIC_ which will include all of the numeric variables.) inFormat= specifies the inFormat that you want to use for the conversion. (The default is the BEST12. informat.) libRef= allows the user to specify a libRef for the library where this macro will write it's temporary datasets. This library will be in a subdirectory named CHAR2NUM under the directory that SAS is using for the WORK library. (The default is ________ in hopes that it is not used by the caller of this macro.) debugging= is set to 1 to evoke debugging options. (The default is 0.)

AUDIT TRAIL: 20060127 EH Developed macro to convert character variables to numeric while preserving the variable order. 20060829 EH Copied the %CHAR2NUM() macro and adapted to convert numeric variables to character. This macro has not been tested! ************************************************************************ *******/ %macro num2char( data=&sysLast , out=_data_ , numVars=_numeric_ , inFormat=best16. , libRef=________ , debugging=0 ) ;

%let data = &data ; /* This assignment is critical. */ %local path allVars renamers drops assignments ;

/* Find the Windows directory for the WORK library and create a subdirectory under that with the name of this macro. Then create a libRef to that subdirectory. This Windows directory will be deleted when SAS automatically cleans up the WORK directory. */ Data _null_ ; Call symPut( 'path' , dCreate( "&sysJobId" , "%sysFunc( pathName(work) )" ) ) ; Run ; LibName &libRef "&path" ;

/* Create a dataset containing the names of all of the variables in the input dataset. This will be used to create an ordered list of the macro variables, so we also need the variable number. */ Proc contents data=&data out=&libRef..AllVars( keep= name varNum ) noPrint ; Run ;

/* Create a dataset containing the names of all of the desired character variables. */ Proc contents data=&data( keep=&numVars ) out=&libRef..NumVars( keep= name type ) noPrint ; Run ;

Proc sql noPrint ; /* Create an ordered list of all of the variable names in the input dataset. Put the list in a macro variable so that it can be used in a RETAIN statement below. */ Select name into :allVars separated by ' ' from &libRef..AllVars order by varNum ; Drop table &libRef..AllVars ; Select /* Create a list of rename clauses that will rename the variables in the NUMVARS= list by preceding the name with an underscore. This list will be used in a RENAME= dataset option. */ catT( name , '=_' , name ) /* Create a list of the variable names from the NUMVARS= list where each variable name is preceded by an underscore. This list will be used in a DROP= dataset option. */ , catT( '_' , name ) /* Create a list of assignment statements that convert the numeric value from the input dataset to a character value for the output dataset. */ , catT( name , '=put(_' , name , ",&inFormat);" ) into :renamers separated by ' ' , :drops separated by ' ' , :assignments separated by ' ' from &libRef..NumVars where ( type eq 1 ) ; Drop table &libRef..CharVars ; Quit ;

/* In case any variables were specified that are already character, issue an warning message to the log. */ Data _null_ ; Set &libRef..NumVars( where=( type ne 1 ) ) ; Put "WARNING:" +1 name "is not a numeric variable." ; Run ; Proc sql noPrint ; Drop table &libRef..NumVars ; Quit ; LibName &libRef clear ;

/* Now, convert the data. */ Data &out( drop=&drops ) ; Retain &allVars ; Set &data( rename=(&renamers) ) ; &assignments Run ;

%mEnd num2char ; /*====================================================================== ======*/

Ed

Ed Heaton RW-4541 #4818

__________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com


Back to: Top of message | Previous page | Main SAS-L page