I have a csv file delimited by semicolon but I have a field with semicolons inside. It it delimited by {}.
An example of the field (it's name is "neighborhood") would be:
{"T":0,"N":"jardim Atlantico","I":0}
But in some lines I could have:
{"T":0,"I":0,"N":"JD";"Sorocaba parque"}
So when I run
proc import
datafile='D:\nnl_muest_result_bs.csv'
dbms=dlm
out=muest_Re.I03_nnl_result_bs;
delimiter=';';
guessingrows=32767;
run;
It splits by the semicolon, which is ok for the rest of the fields but not in this one.
How can I tell SAS to split using semicolon but to ignore those inside curly braces {}??
Thanks
I haven't found anything useful with proc import but you can solve the problem with a more manual approach.
I created some test data:
a;b;n{c;d}e;g
aa;bb;mm{cc;dd;ee}ff;h
and here is the code where the commented part has to be modified according to your variables as is the length of record (and you maybe need to add a lrecl= and firstobs=2 in the infile statement)
data test;
infile "C:\Dati\EsempiSAS\graffe.txt" pad missover;
input #1 record $CHAR100.;
piece1=substr(record,1,indexc(record,"{")-1);
piece2=substr(record,indexc(record,"{")+1,(indexc(record,"}"))-(indexc(record,"{")+1));
piece3=substr(record,indexc(record,"}")+1);
/*
var1=scan(piece1,1,";");
var2=scan(piece1,2,";");
var3=scan(piece1,3,";");
var4=piece2;
var5=scan(piece3,1,";");
var6=scan(piece3,2,";");
*/
run;
Related
I tried to import text file in sas with the following code
PROC IMPORT DATAFILE= '/home/u44418748/MSc Biostatistics with SAS/Datasets/school.txt'
OUT= outdata
DBMS=dlm
REPLACE;
delimiter='09'x;
GETNAMES=YES;
RUN;
But I am getting import unsuccessful because text file has period for missing data
this is what i got in SAS log
NOTE: Invalid data for class_size in line 455 16-17.
455 CHAR 454.34.8.32.17.NA.23.125.12.188 31
ZONE 3330330303303304403323330332333
NUMR 454934989329179E1923E125912E188
sl_no=454 school=34 iq=8 test=32 ses=17 class_size=. meanses=23.125 meaniq=12.188 _ERROR_=1 _N_=454
how can load this text file in SAS
Did you create that text file from R? That package has a nasty habit of putting text values of NA for numeric values into text files. If you are the one that created the file the you might check if the system you are using has a way to not put the NA into the file to begin with. In a delimited file missing values are normally represented by having nothing for the field. So the delimiters are right next to each other. For SAS you can use a period to represent a missing value.
I wouldn't bother to use PROC IMPORT to read a delimited file. Just write a data step to read the file. Since it looks like your file only has six variables and they are all numeric the code is trivial.
data outdata;
infile '/home/u44418748/MSc Biostatistics with SAS/Datasets/school.txt'
dsd dlm='09'x firstobs=2 truncover
;
input sl_no school iq test ses class_size meanses meaniq ;
run;
One way to deal with the NA text in the input file is to replace them with periods. Since all of the fields are numeric you can do that easily because you don't have to worry about replacing real text that just happens to have the letter A after the letter N. Here is trick using the _INFILE_ automatic variable that you can use to make the change on the fly while reading the file.
data outdata;
infile '/home/u44418748/MSc Biostatistics with SAS/Datasets/school.txt'
dsd dlm='09'x firstobs=2 truncover
;
input #;
_infile_=tranwrd(_infile_,'NA','.');
input sl_no school iq test ses class_size meanses meaniq ;
run;
You are getting the NOTE: because of the NA value in the class_size field.
What you presume are periods (.) are actually tabs (hex code 09). Look under the period to confirm, the ZONE is 0 and NUMR 9. 09 is the tab character.
Proc IMPORT guesses each fields data type based on looking at the first few rows (default is 20 rows) of a text file. Your file contained only numbers the 20 rows, so the procedure guessed class_size was numeric.
There a couple of courses of action.
Do nothing. Read your log NOTES and know the places where NA occurred you will have a missing value in your data set.
or,Read the file as-is, but add GUESSINGROWS=MAX; statement to your import code
The mixed data type column class_size will be guessed as character and you might have to do another step to convert the values to numeric (a step in which the non-digit values get converted to missing values)
or, Edit the text file replacing all the NA with a period (.). The dot marks a missing value during IMPORT. The IMPORT step will have no incongruities to LOG about.
Converting a field
PROC IMPORT DATAFILE= '/home/u44418748/MSc Biostatistics with SAS/Datasets/school.txt'
DBMS=dlm REPLACE OUT=work.outdata;
delimiter='09'x;
GETNAMES=YES;
GUESSINGROWS=MAX;
RUN;
data want;
set outdata (rename=(class_size=class_size_char));
class_size = input (class_size_char, ?? best12.);
drop class_size_char;
run;
Sometimes if I import multiple SAV files into the SAS work library, one variable imported later on overwrites the display text (i.e., the format) of an earlier imported variable with a similar name.
I've determined that this is because the later dataset's variable produces a format name for the custom format (from SPSS Values Labels) that is identical to format name from the earlier variable, even though the variables have different definitions in the Value Labels attributes in the SAV files.
Is there a way to force SAS to not re-use the same format names by automatically checking at PROC IMPORT whether a format name already exists in the work library format library before auto-naming a new custom format? Or is there any other way of preventing this from happening?
Here is my code as well as an example of the variable names, format names, etc.
proc import out=Dataset1 datafile="S:\folder\Dataset1.SAV"
dbms=SAV replace;
run;
proc import out=DatasetA datafile="S:\folder\DatasetA.SAV"
dbms=SAV replace;
run;
Dataset1 contains variable Question_1. The original SPSS Values Labels are 1=Yes 2=No. When this dataset is imported, SAS automatically generates the Format Name QUESTION., for Question_1. When only Dataset1 is imported, the definition of format QUESTION. corresponds to the SPSS Value Labels for Question_1 in Dataset1.SAV
DatasetA contains variable Question_A with SPSS Value Labels 1=Agree 2=Unsure 3=Disagree. When this dataset is imported after Dataset1, SAS automatically generates the Format Name QUESTION. for Question_A, even though the work library already contains a format named QUESTION.. Therefore, this overwrites the definition of format QUESTION. that was generated when Dataset1 was imported. Once DatasetA is imported, the definition of format QUESTION. corresponds to the SPSS Value Labels for Question_A in DatasetA.SAV
Therefore, when Dataset1 and DatasetA are both imported, Variable Question_1 and Question_A both have the format name QUESTION assigned to them - And the definition of the format QUESTION. in the SAS work folder corresponds to the SPSS Value Labels in DatasetA.SAV, not Dataset1.SAV. Therefore, Question_1 will display as 1=Agree 2=Unsure, even though the variable values actually mean 1=Yes 2=No.
I would ideally like for these two variables to produce distinct custom format names at their import step, automatically. Is there any way to make this happen? Alternatively, is there any other way that prevent this type of overwriting from occurring?
Thank you.
The way to prevent literal overwriting is to point to a different format catalog for each SPSS file that is being read using the FMTLIB= optional statement.
proc import out=dataset1 replace
datafile="S:\folder\Dataset1.SAV" dbms=SAV
;
fmtlib=work.fmtcat1;
run;
proc import out=dataset2 replace
datafile="S:\folder\Dataset2.SAV" dbms=SAV
;
fmtlib=work.fmtcat2;
run;
You can then work later to rename the conflicting formats (and change the attached format in the dataset to use the new name).
So if the member name and format name are short enough you should be able to generate a unique new name by appending the two (add something in between to avoid conflict). So something like this will rename the formats, change the format name attached to the variables and rebuild the formats into the WORK.FORMATS catalog.
%macro sav_import(file,memname);
%if 0=%length(&memname) %then %let memname=%scan(&file,-2,\./);
proc import datafile=%sysfunc(quote(&file)) dbms=save
out=&memname replace
;
fmtlib=work.&memname ;
run;
proc format lib=work.&memname cntlout=formats;
run;
data formats ;
set formats end=eof;
by fmtname type notsorted;
oldname=fmtname;
fmtname=catx('_',"&memname",oldname);
run;
proc contents data=&memname noprint out=contents;
run;
proc sql noprint;
select distinct catx(' ',c.name,cats(f.fmtname,'.'))
into :fmtlist separated by ' '
from contents c inner join formats f
on c.format = f.oldname
;
quit;
proc datasets nolist lib=work;
modify &memname;
format &fmtlist ;
run;
quit;
proc format lib=work.formats cntlin=formats;
run;
%mend sav_import;
%sav_import(S:\folder\Dataset1.SAV);
%sav_import(S:\folder\Dataset2.SAV);
I have a text file "Macro definition" which has two SAS macros definition. I would like to import them and apply on HTWT.csv data set. This dataset has 20 observations and 6 variables ID, Gender, Age,Height,Weight,Year. All are numeric except gender variable. I have the code below to import and apply the macros from the txt file to csv file. I am getting an error message on running this code as below.
outcsvv is the name of HTWT dataset imported in SAS.
%include "C:\Users\komal\Desktop\Advanced SAS\Macro definition.txt";
%contents_of(outcsvv)
%print_data(outcsvv)
Warning:Apparent Invocation of macro "contents_of" not resolved
Error: Unable to complete processing of INCLUDE. Expected a filename or fileref
Expected a statement keyword: found "("
The second error I am getting is probably due to the macro definition(s) from the text file which are as follows.
%macro contents_of(name);
proc contents data=&name;
run;
%mend;
%macro print_data(name);
proc print data=&name;
run;
%mend;
Please let me know your advice on how to solve it. Thank you for your time.
You can setup your own macro Autocall Library. Just split your file; save one macro per-file. more.
or you can add this code to the begining of your program:
options insert=(sasautos="/C:\Users\komal\Desktop\Advanced SAS") ;
this will search for the macros in this directory.
My first question as a new user of SAS 9.3. I want to use proc import to read a large text file with dlm=’,’. But there is one variable has “,” in between in some obs, eg. “Hartford, CT”. (not all of them, others like “XL Center”).IS there any way that I can read “Hartford, CT” into one variable just like “XL Center” while using proc import to this text file?
Many thanks
Edited here: sorry I shouldn't put quote around the record. there are NO quotes wrap on any record, be XL center, or Hartford, CT. when dlm set as comma, the row has Hartford, CT produces on extra column and shifts records into wrong column afterwards.
So long as your text file has quotes around the delimeter, then it will work automatically. For example:
/* example data */
data _null_;
file "%sysfunc(pathname(work))/some.csv";
put 'head1,head2,head3';
put 'XL Center,1,"Hartford, CT"';
run;
/* import */
proc import datafile="%sysfunc(pathname(work))/some.csv"
out=example
dbms=dlm
replace;
delimiter=",";
datarow=2;
run;
I have a problem with SAS 9.2.
I'm writing a simple macro which creates dataset and name it according to the variables submitted and some other words/letters/signs, for example
%macro example(var1,var2);
data &var1 || '_word_' || &var2;
a=1;
run;
%mend;
Can anyone help?
Pipes are only for strings within SAS, not within SAS macro. So don't use them here.
SAS Macro does not interpret quotes as indicating a string, it will just read them, so leave out the quotes.
If you want to concatenate elements in macro, you just need to write them appended to each other.
To make clear where the macro variable name ends, append a dot.
This should work:
%macro example(var1,var2);
data &var1._word_&var2.;
a=1;
run;
%mend;