BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
ANKH1
Pyrite | Level 9

Hi, I ran the following code and the symbol "-" is not recognized. I cannot change it since I am importing more than 100 csv files with the symbol "-" in most of the file names. Is there a way for SAS to recognize the symbol?

data TEST.ABC-POST;
%let _EFIERR_ = 0; /* set the ERROR detection macro variable */
infile "&DATA_PATH.CSV files/ABC-POST.csv" delimiter=','
...
run;

This is the log:

207        
 208        
 209        *ABC-POST variables;
 210        data TEST.ABC-POST;
                           _
                           22
                           200
 ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, (, /, ;, _DATA_, _LAST_, _NULL_.  
 
 ERROR 200-322: The symbol is not recognized and will be ignored.

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

A CSV file is just a file. It can have any name it wants.  But a SAS dataset's name has to follow SAS's rules.

So just generate a valid SAS name to use as the dataset member name.  

data TEST.ABC_POST;
  infile "&DATA_PATH.CSV files/ABC-POST.csv" dsd firstobs=2 truncover;
  length var1 8 var_next $32 .... var_last 8;
  input var1 -- var_last;
run;

If you can't find one just use a number.

data have;
  infile cards truncover;
  length row 8 memname $32 filename $256 ;
  row+1;
  input filename $256.;
  memname=scan(filename,-2,'./\');
  if not nvalid(memname,'v7') then memname=cats('csv',row);
cards;
&DATA_PATH.CSV files/ABC-POST.csv
normal.csv
this_name_is_going_to_be_way_too_long_to_use_as_dataset_name.csv
;

Tom_0-1677183552644.png

 

 

 

View solution in original post

4 REPLIES 4
Tom
Super User Tom
Super User

A CSV file is just a file. It can have any name it wants.  But a SAS dataset's name has to follow SAS's rules.

So just generate a valid SAS name to use as the dataset member name.  

data TEST.ABC_POST;
  infile "&DATA_PATH.CSV files/ABC-POST.csv" dsd firstobs=2 truncover;
  length var1 8 var_next $32 .... var_last 8;
  input var1 -- var_last;
run;

If you can't find one just use a number.

data have;
  infile cards truncover;
  length row 8 memname $32 filename $256 ;
  row+1;
  input filename $256.;
  memname=scan(filename,-2,'./\');
  if not nvalid(memname,'v7') then memname=cats('csv',row);
cards;
&DATA_PATH.CSV files/ABC-POST.csv
normal.csv
this_name_is_going_to_be_way_too_long_to_use_as_dataset_name.csv
;

Tom_0-1677183552644.png

 

 

 

ANKH1
Pyrite | Level 9

Ok, so manually change in the SAS datasets' names the "-" to "_". I didn't understand your second option. What do you mean if I cannot find one just use a number? Sorry, I'm new to programming.

Tom
Super User Tom
Super User

@ANKH1 wrote:

Ok, so manually change in the SAS datasets' names the "-" to "_". I didn't understand your second option. What do you mean if I cannot find one just use a number? Sorry, I'm new to programming.


You mentioned you wanted to convert a LOT of files.  So rather than generating all of that code manually you could use a PROGRAM to read the list of files and generate the code.  So how is the PROGRAM going to know what is a valid SAS name to use for any given CSV filename?  One way is to not even try, instead just number the files and use the number to generate the names.  So the first file could be used to create a dataset named CSV1 and the second file to create a dataset named CSV2.  You could actually use the original filename as the label or part of the label for the dataset to help you find the right dataset later.

data csv1(label="Strange file - name.csv");
  infile "Strange file - name.csv" dsd firstobs=2 truncover;
   ...
run;
data csv2(label="Another strange file - name.csv");
  infile "Another strange file - name.csv" dsd firstobs=2 truncover;
   ...
run;

 

Here is an example of logic I used in the %csv2ds() macro to make sure each name is valid. 

See if you can figure out from reading the help for the functions used what it is doing.

* Replace adjacent non-valid characters with single underscore ;
    name=translate(trim(prxchange('s/([^a-zA-Z0-9]+)/ /',-1,name)),' _','_ ');
    name=prxchange('s/(^[0-9])/_$1/',1,name);
Reeza
Super User
Your code as shown is invalid and will not work. You cannot place multiple file paths in the infile statement in this method.

Instead, you can create a data set with the list of files to be read, so it contains the filepath and/or file name. Then within that file, you can check if the dataset name is a valid SAS data set name. If not, you can change it there.
Then you can use that dataset to generate appropriate SAS code to read each file.

When you're starting out a process like this, the best approach is to first read a few files manually to ensure your code is correct and then figure out how to generalize it for all your files.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 575 views
  • 2 likes
  • 3 in conversation