I am trying to create a new permanent SAS data set with the following variables.
data bone; infile "\\apporto.com\dfs\GWU\Users\kennedyhinnant_gwu\Downloads\Assignment 4\bone.txt"; input @1 dob 1-10. @11 dov 11-20. @21 wt $ 21-26. @27 ht 27-30. @31 peri $ 31-35. endo $ 35-40 tibia $ 41-44 tanner 45 sex 46; age = (dov - dob)/365; logperi = log(peri); run;
181 data bone;
182 infile "\\apporto.com\dfs\GWU\Users\kennedyhinnant_gwu\Downloads\Assignment 4\bone.txt";
183 input @1 dob 1-10. @11 dov 11-20. @21 wt $ 21-26. @27 ht 27-30. @31 peri $ 31-35.
--- ---
22 22
ERROR: Invalid decimal specification.
183 input @1 dob 1-10. @11 dov 11-20. @21 wt $ 21-26. @27 ht 27-30. @31 peri $ 31-35.
---
22
ERROR 22-322: Expecting an integer constant.
ERROR: The ending column position 1 is before the starting column position 11.
ERROR: Invalid decimal specification.
183 input @1 dob 1-10. @11 dov 11-20. @21 wt $ 21-26. @27 ht 27-30. @31 peri $ 31-35.
---
22
ERROR 22-322: Expecting an integer constant.
ERROR: The ending column position 1 is before the starting column position 21.
ERROR: Invalid decimal specification.
ERROR: The ending column position 1 is before the starting column position 27.
ERROR: Invalid decimal specification.
183 input @1 dob 1-10. @11 dov 11-20. @21 wt $ 21-26. @27 ht 27-30. @31 peri $ 31-35.
---
22
ERROR 22-322: Expecting an integer constant.
184 endo $ 35-40 tibia $ 41-44 tanner 45 sex 46;
ERROR: The ending column position 1 is before the starting column position 31.
ERROR: Invalid decimal specification.
185 age = (dov - dob)/365;
186 logperi = log(peri);
187 run;
NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column).
186:15
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.BONE may be incomplete. When this step was stopped there were 0
observations and 11 variables.
WARNING: Data set WORK.BONE was not replaced because this step was stopped.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.03 seconds
The variable that receives a value appears on the LEFT of the equal sign.
instead of:
log(peri) = logperi;
use
logperi = log(peri);
You are using column input which lists the from-to column. This syntax doesn't require a period.
Column input also doesn't require pointer control @<n> because you're defining the start and end columns already explicitly.
Assuming dob is Date of Birth and in your source data you've got something like 20Mar2001, trying to read this string as a number will fail. What you need to do is provide SAS the instruction how to read and convert the source string to a SAS Date value. That's done via an INFORMAT. Using the appropriate informat will read the source string and convert it into a SAS Date value (count of days since 1/1/1960). Applying a FORMAT will then print this count of days in a human readable form as a date.
For a blank delimited source file like...
...code as below would work.
data bone;
infile "c:\temp\bone.txt" dsd dlm=' ' truncover;
input dob :date9. dov :date9. wt $ 21-26;
format dob dov date9.;
age = yrdif(dob,dov,'age');
logperi = log(peri);
run;
To calculate the age: Use function yrdif() which handles even leap years.
If you want to create a permanent SAS data set that doesn't get automatically deleted after your SAS session ends then you need to a) define a libname that points to permanent storages and b) use a two level name with the libref in your data statement <libref>.<table name>
And last but not least: Lookup the INFILE statement and what the highlighted parameters below do for you.
@MisterJenn This is a template for you to do some own work.
Are you trying to read the data using column mode input?
If so why did you also include cursor motion commands? Those are not needed as to start and stop columns are already included.
Are you trying to have SAS insert an implied decimal point into your numbers? If so then you need to include the number of implied decimal places after the period. If not then why did you include a decimal point after the ending column number?
Is PERI supposed to be a numeric value? If so then why did you create it as a character variable by including the $ in the INPUT statement? If not then why are you trying to pass a character string to the LOG() function?
Does your source file have the DOV and DOB variables stored as the raw number of days since 1960 ? If so then why would they need 10 columns in the source text file? The value that represents today is 22,928 which only needs 5 characters. And if you have any 120 year olds in your data the value that represents 01JAN1900 is -21,914 which only needs 6 characters including the minus sign.
1247 data _null_; 1248 today=date(); 1249 jan1900 = '01JAN1900'd ; 1250 put (_all_) (=comma10./); 1251 run; today=22,928 jan1900=-21,914
You probably need to use an informat with the DOV and DOB variables.
You cannot tell SAS to use an informat when using column mode input. So you will want switch to a hybrid method that uses column mode for most of the variables and formatted mode to handle the two date values.
You don't say how the dates are entered so let's assume the 10 character strings in your text file are in a style that the YYMMDD informat can read. So something like 2022-10-10 for example. Then your INPUT statement might look more like:
input dob yymmdd10. dov yymmdd10. wt 21-26 ht 27-30 peri 31-35
endo 35-40 tibia 41-44 tanner 45 sex 46
;
And you will probably also want to attach a FORMAT to DOB and DOV so that they print in a style that is easier for humans to understand than values like 22,928 or -21,914.
format dob dov yymmdd10.;
If you really don't know how the dates are represented (or they are inconsistent) then you could try using the ANYDTDTE. informat instead. That will try to guess what type of style the strings are using and adjust.
And if you want to make a PERMANENT dataset then don't want to use a one level dataset name. Instead create a libref that points to some directory on your machine and use a two level name.
libname perm "\\apporto.com\dfs\GWU\Users\kennedyhinnant_gwu\Downloads\Assignment 4\";
data perm.bone;
infile "\\apporto.com\dfs\GWU\Users\kennedyhinnant_gwu\Downloads\Assignment 4\bone.txt" truncover;
input dob yymmdd10. dov yymmdd10. wt 21-26 ht 27-30 peri 31-35
endo 35-40 tibia 41-44 tanner 45 sex 46
;
format dob dov yymmdd10.;
age = (dov - dob)/365;
logperi = log(peri);
run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.