I have a data set that I have created and it needs to be formatted to have trailing/padded spaces to the specified number of characters.
Below are the field names from the STG data set.
'Social Security Number (SSN)'n
'Date of Birth'n
'Last Name'n
'First Name'n
SSN must start at position 1 and only be 9 characters long (position 1-9)
DOB must start at position 10 and be 8 characters long (position 10-17)
Last Name must start at position 18 and be 26 characters long (position 18-43)
First Name must start at pisition 44 and be 20 characters long (position 44-63)
so on and so forth.
When exported, I need to be able to see the padded/trailing spaces stored in the string. All my fields are formatted as character.
What is the best way to approach this? I've tried specify length and subpad in a data step but when exported, the trailing spaces are lost.
It is pretty trivial to generate a fixed column text file. Just use the PUT statement.
You can force fixed length lines by writing a space into the last column before writing the actual values. That will insure that all lines are padded to at least that length.
data _null_;
file 'mydata.txt' ;
set have;
put #63 ' '
# 1 SSN $9.
#10 DOB yymmdd8.
#18 LAST_NAME $26.
#44 FIRST_NAME $20.
;
run;
Related
I can't get why there isn't $ between Age and Weight like there is for others
enter image description here
And Why the missing value is denoted by blank in row 2 but period(.) in row 4
enter image description here
Please help with such questions, I'm new to SAS and it's so miserable when I asked my colleagues, and nobody was willing to answer...
The $ after name and gender indicates that those variables are character variables. The other variables are numeric variables. Those are the only 2 data types in SAS.
Missing values for character variables are blanks while missing values for numeric variables are shown with a period.
The $ modifier in a INPUT statement let's SAS know that it should treat the preceding variable as CHARACTER instead of numeric. It is only needed when you have not previously already told SAS that the variable is character, because the default assumption is that a variable is numeric.
The normal character informat, $, which is what your code used because it did not specify any other informat for NAME or SEX, will convert a single period into blanks, which is how SAS stores an empty character value. If you want SAS to input a single period as an actual single period you would need to use the $CHAR informat instead. So if you modified the input statement like this:
input name $ sex :$char1. age weight ;
then the value of SEX would be the one byte string '.' (since the width of the informat gave SAS better information about what length to use to define the variable) instead of the current 8 character string of blanks ' '.
The normal way to display a missing numeric variable is as a single period. You can change to have it display some other single character instead by changing the setting of the MISSING option. For example to have the missing values of AGE print as blank also you could add this OPTIONS statement before you print it.
options missing=' ';
I have a problem with aligning column with 'min, max' and 'q1, q3'. I have predetermined number format and I cannot change it. Five digit number and four digit number cause an error. I would like to have only one space AFTER comma. In column B problem is.
Can I somehow break down column by comma and glue it again?
I have no idea.
I work in SAS.
Thanks in advance!
You can use compbl to remove double spaces in strings:
The COMPBL function removes multiple blanks in a character string by
translating each occurrence of two or more consecutive blanks into a
single blank.
Documentation
B = compbl(B);
You can leave your structure as-is. The code below will remove double spaces from all character variables.
data want;
set have;
array charvars[*] _CHARACTER_;
do i = 1 to dim(charvars);
charvars[i] = compbl(charvars[i]);
end;
drop i;
run;
I have a SAS dataset. When I 'View Columns', I find a column with Type=text, length=3, informat = $3., format=$3.
The value stored in this variable is 10.
But based on the attributes, should it not be stored as 010?
The attributes say you have a character variable that can hold 3 bytes (normal character encodings use one byte per character). You could store '010' in that variable or '10 ' or even ' 10'. You could also store 'ABC' or 'abc'. It is just a character variable. Note that SAS always stores fixed length character fields so shorter values are padded with spaces.
It also has optionally added the FORMAT metadata saying that when displaying the value SAS should use the $3. format. Similarly is has optional metadata that says when reading text it should use the $3. informat to convert incoming text into the value to be stored.
This metadata is NOT needed because SAS already knows how to read and display character data. If you did store values with leading spaces you might want to attach the $CHAR3. format instead so that the leading spaces are preserved when writing the value.
As the variable is just text, it will just store what it is assigned. For example:
data have;
length var1 $ 3;
informat var1 $3.;
format var1 $3.;
input var1;
datalines;
10
010
;
The fact that it has a format of $3. will not cause it to be prefixed with a leading 0, as you will see from the documentation of the $w. format, where that is not mentioned. Also, the value could later be changed to 'ab'; in both cases the value is padded with a trailing space to make up the length of 3.
Can anyone help me to resolve this?
I have a very large raw dataset with a character variable that contains text strings along with numbers & dates defined in character format. Now I want to process the dataset and create a new numeric variable and populate values only when the text in the actual variable is either a number or a date value. Otherwise missing
RAWDATA:
ACTUAL_VARIABLE NEW_NUM_VARIABLE(Expected Values)
------------------ ---------------------------------
ODed on pills threw them all up - 2006
Y
1 1
5 5
ODed on pills
6 6
Less than once a week
N
N
2006-11-12 2006-11-12
Many Thanks in Advance
The easy way to do it (if you know the specific date format) is to use the input function.
09:27
If put(input(var,??yymmdd10.),yymmdd10.)=var then its a date!
else if input(var,best.) ne . then its a number.
Otherwiseits a character string.
This isn't as straightforward as it first looks, so I understand why it would be difficult to search for an answer. Just extracting a number is pretty easy, but when dates are included it becomes a bit more complicated (particularly when the format entered could change, e.g. yyyy-mm-dd, dd-mm-yyyy, dd/mm/yy etc).
One thing to note first. If you want to store the new values as a numeric field then you can't show a mix of numbers and dates. Dates are stored as numbers and formatted to show the date, but you can't apply a format at row level. Therefore I would suggest creating 2 new columns, 1 for numbers and 1 for dates.
My preferred approach is to use the anyalpha function to exclude any records with an alphabetic character, followed by the anypunct function to identify if a punctuation character exists (this should identify dates rather than just numbers). The anydtdte informat is then used to extract the date, this is a very useful informat as it reads dates stored in different ways (as per my note above).
There are clearly some caveats with this method.
If any numbers contain decimals then my method would incorrectly treat these as dates, therefore only integers will be assigned correctly.
It won't pick up dates that contain the month as words, e.g. 15-May-2015, as the anyalpha function would exclude them. They will need to contain numbers only, separated by any punctuation character.
Here's my code.
/* create initial dataset */
data have;
input actual_variable $ 50.;
datalines;
ODed on pills threw them all up - 2006
Y
1
5
ODed on pills
6
Less than once a week
N
N
2006-11-12
;
run;
/* extract dates and numbers */
data want;
set have;
if not anyalpha(actual_variable) then do; /* exclude records with an alphabetic character */
if anypunct(actual_variable) then new_date_variable = input(actual_variable,anydtdte10.); /* if a punctuation character exists then read in as a date */
else new_num_variable = input(actual_variable,best12.); /* else read in as a number */
end;
format new_date_variable yymmdd10.; /* show date field in required format */
run;
In the following code
data temp2;
input id 1 #3 date mmddyy11.;
cards;
1 11/12/1980
2 10/20/1996
3 12/21/1999
;
run;
what do 1 #3 symbols mean ? i presume 1 means that id is the first character in the data . I know that #3 means that date variable starts with the third character , but why is it in front of date whereas 1 is after id?
Because that's a badly written input statement. You can specify input in a number of ways, and that mixes a few different ways to do things which happen to be allowed to mix (mostly). Read the SAS documentation on input for more information.
Some common styles that you can use:
input #1 id $5.; *Formatted input. Allows specification of start position and informat, more useful if using date or other informat that is not just normal character/number.;
input id str $ otherstr $ date :date9.; *List input. This is for delimited text (like a CSV), still lets you specify informat.
input #'ID:' id $5.; *A special case of formatted input. allows you to parse files that include the variable name, useful for old style files and some xml/json/etc. type files;
input x 1-10 y 11-20; *Column input. Not used very commonly as it's less flexible than start/informat style.;
There are other options (such as named input) that are not very frequently used in my experience.
In your specific example, the first variable is read in with column input [id 1 says 'read a 1 character numeric from position 1 into id'] and then the second variable is read with formatted input [#3 date mmddyy11. says 'Read an 11 character date variable from position 3[-13] into a numeric using the date informat to translate it to a number.'] It also says someone gave you that code who isn't very familiar with SAS, since mmddyy10. is the correct informat - the 11th character cannot be helpful.