Changing the language you use might help a little understanding how to approach this problem. You are not "importing" the file. Instead you just need to read the file. Use the work "import" for when moving data from a structured file/system into SAS dataset. The PROC IMPORT procedure has to guess how to read data from a CSV file. The only metadata a CSV file has is the optional header row and it sounds like your file does not even have that.
Since you have the information needed to define the variables you can simply use that to define the variables. So take your table of metadata and put it into a SAS dataset so you have something to code with.
data metadata;
infile cards dsd dlm='|';
input FieldName :$32. Length DataType :$20. Import_in_SAS :$1.;
cards;
YEAR|4|AN|Y
MSA|5|AN|Y
STATE|2|AN|Y
COUNTY|3|AN|Y
TRACT|6|AN|Y
CITY|1|AN|Y
SMALL_COUNTY|1|AN|N
TRACT_FLAG|1|AN|Y
COUNTY_FLAG|1|AN|N
URBAN_RURAL|1|AN|Y
INCOME_MSA|8|NUM|Y
INCOME_FAMILY|8|NUM|Y
INCOME_TRACT|8|(DECIMAL 6,2)|Y
INCOME_FFIEC|8|NUM|Y
TOTAL_PERSONS|8|NUM|Y
TOTAL_FAMILIES|8|NUM|Y
TOTAL_HHLDS|8|NUM|Y
TOTAL_FEMALES|8|NUM|Y
TOTAL_MALE|8|NUM|N
;
So the first thing you need to do is convert that metadata into something that is useful for representing a SAS dataset. SAS has just two data types, floating point numbers and fixed length character strings. So your 'NUM' and '(DECIMAL 6,2)' datatypes will probably be mapped to numbers. Let's assume your 'AN' datatype should be character. In SAS the LENGTH of a variable defines how many bytes it uses when stored in the dataset. But normally for metadata about a text file you want to know the number of bytes the value will take in the text file, which is more like the width you might need for a format to display the data as text or for an informat to read that text into data. It is not clear what LENGTH in your metadata represents as the values are compatible with either meaning. In SAS you want numeric variables to use LENGTH=8 since it takes 8 bytes to store the floating values SAS uses for numbers. SAS variable names contain only letters, digits and underscores and are a length between 1 and 32 bytes. Plus they cannot start with a digit. It looks like your example FIELDNAME values will work. You don't have any information on what informat or format you might need attached to the variables. Normally you only need those for date, time and datetime values, but you might want to use the F6.2 format for your '(DECIMAL 6,2)' data type so that it prints with only two decimal places.
Your metadata does not have anything to indicate the order of the variables, but we could assume they are in the same order as they were displayed in your listing. In more complete metadata you might need two order variables. One for the order you want the variables defined in your SAS dataset and one for the order they will appear in the text file you want to read. Let's assume you want to use the same order for both.
So take the metadata and use it to generate code to define the variables. For example this code will generate a series of ATTRIB statements to define the variables. Then and INPUT statement to read all of the variables. Then a KEEP statement to only keep the variables you want. You can then use %INCLUDE to add those to a data step where you specify the dataset you want to create and the file you want to read.
filename code temp;
data _null_;
file code ;
* Define the variables using ATTRIB statement ;
do varnum=1 to nobs;
set metadata point=varnum nobs=nobs;
put ' attrib ' fieldname 'length=' @;
if datatype='AN' then put '$' length @;
else put '8 ' @;
if datatype=:'(DECIMAL' then do;
format=cats('F',tranwrd(scan(datatype,2,' )'),',','.'));
put format= @;
end;
put ';';
end;
* write the input statement ;
put ' input ' @;
varnum=1;
set metadata point=varnum;
put fieldname '-- ' @;
varnum=nobs;
set metadata point=varnum;
put fieldname ';' ;
* Write KEEP statement ;
put ' keep ' @;
do varnum=1 to nobs;
set metadata point=varnum nobs=nobs;
if upcase(import_in_sas)='Y' then put fieldname @ ;
end;
put ';' ;
* Need an explicit stop since step will not read past input ;
stop;
run;
data want;
infile 'myfile.csv' dsd truncover ;
%include code / source2;
run;
So code might look like this :
691 data want;
692 infile 'myfile.csv' dsd truncover ;
693 %include code / source2;
NOTE: %INCLUDE (level 1) file CODE is file
...\#LN00072.
694 + attrib YEAR length=$4 ;
695 + attrib MSA length=$5 ;
696 + attrib STATE length=$2 ;
697 + attrib COUNTY length=$3 ;
698 + attrib TRACT length=$6 ;
699 + attrib CITY length=$1 ;
700 + attrib SMALL_COUNTY length=$1 ;
701 + attrib TRACT_FLAG length=$1 ;
702 + attrib COUNTY_FLAG length=$1 ;
703 + attrib URBAN_RURAL length=$1 ;
704 + attrib INCOME_MSA length=8 ;
705 + attrib INCOME_FAMILY length=8 ;
706 + attrib INCOME_TRACT length=8 format=F6.2 ;
707 + attrib INCOME_FFIEC length=8 ;
708 + attrib TOTAL_PERSONS length=8 ;
709 + attrib TOTAL_FAMILIES length=8 ;
710 + attrib TOTAL_HHLDS length=8 ;
711 + attrib TOTAL_FEMALES length=8 ;
712 + attrib TOTAL_MALE length=8 ;
713 + input YEAR -- TOTAL_MALE ;
714 + keep YEAR MSA STATE COUNTY TRACT CITY TRACT_FLAG URBAN_RURAL
714 !+INCOME_MSA INCOME_FAMILY INCOME_TRACT INCOME_FFIEC TOTAL_PERSONS
714 !+TOTAL_FAMILIES TOTAL_HHLDS TOTAL_FEMALES ;
NOTE: %INCLUDE (level 1) ending.
715 run;
... View more