BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
AshleyBright
Obsidian | Level 7

I have delimiter separated data values that are generated like this:

abc|def ghi|jkl

mno|pqr|stu||vw

x|y|z

 

How do I get all of these into one observation? I also have the the column names in input statement. Can someone please help. Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

You cannot use CARDS (aka DATALINES) inside a macro.  The macro processor parses the lines and "ruins" them for the SAS processor.  You have demonstrated that when you execute a macro via CALL EXECUTE you can circumvent that restriction.  When CALL EXECUTE() pushed the string to SAS to put on the stack it runs the macro immediately and pushes the generated text onto the stack for the SAS processor.  When the SAS processor pulls the generated code back off of the stack it does not treat it as being in a macro. Which makes sense because by the time the data step ends and SAS starts trying to interpret the code from the stack the macro has ended execution already.

 

The reason you get LOST CARD message is because you haven't given the data step any lines of data. When you use CARDS in-line data stops BEFORE the first line that contains a semi-colon.  Since the macro processor/call execute combination does not generate lines you get something like:

data want; input x y ; datalines; 1 2; 

So there is no data there.

 

Either parse the string yourself. 

Or if you want to use the INPUT statement then create a temporary file and put the text in there and read from there.

%macro createDS(dsname, colnames, colvalues);
filename lines temp;
data _null_;
  file lines;
  put "&colvalues";
run;
data &dsname;
  length &colnames $1000;
  infile lines dlm='|' dsd ;
  input &colnames @@;
run;
filename lines;
%mend createDS;

options mprint;
%createDS(xxx,name value,a|100|b|200|c|300);
proc print;
run;
Obs    name    value

 1      a       100
 2      b       200
 3      c       300

 

View solution in original post

27 REPLIES 27
AshleyBright
Obsidian | Level 7

Thank you @Kurt_Bremser. Basically, I have column names and column values that are generated dynamically and I pass that as macro variable for a dataset creation. Column values always have data for one row.

And I pass those values inside a macro variable and when it resolves, it actually spans multiple lines after datalines. But I want that as one row.. I tried @@/truncover but it's not helping.

AshleyBright
Obsidian | Level 7
It should look like this:

col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 | col9
abc | def ghi | jkl mno | pqr | stu | | vwx | y | z
AshleyBright
Obsidian | Level 7

Problem is when the column values resolve from a macro variable it's getting split into new lines within the datalines...

Kurt_Bremser
Super User

So it seems you have line breaks right within columns, but nothing to recognize them. This cannot be handled reliably.

The only way one can work around such things is if the "non-natural" line breaks look different form those that actually separate records.

AshleyBright
Obsidian | Level 7
But it's actually resolving like this during the macro variable resolution.. Is there a way we can resolve the macro variable in one line to make the data step read the dataline as one whole record?
Kurt_Bremser
Super User

@AshleyBright wrote:
But it's actually resolving like this during the macro variable resolution.. Is there a way we can resolve the macro variable in one line to make the data step read the dataline as one whole record?

Post your code & log, as @PaigeMiller requested.

Astounding
PROC Star

Two suggestions ...

 

First, make sure the INFILE statement uses DSD:

 

infile datalines dlm='|' dsd;

 

Second, is it possible to simplify the INPUT statement:

 

input (col1-col9) ($);

 

Get rid of @@, get rid of TRUNCOVER, and be willing to accept a message that SAS went on to a new line when it reached past the end of the current line.

 

If that's not possible, you will need to provide an example of the names of the macro variables and what each contains,.  You might be able to use:

 

input (&maclist1. &maclist2. &maclist3.) ($);

AshleyBright
Obsidian | Level 7

I have a macro variable that holds column values that I use after datalines statement. When the macro variable is resolved, I can see that it is splitting into different lines in the log which is causing problem. It should all be read as one single row. Can someone please help. Thanks.

PaigeMiller
Diamond | Level 26

Show us your code. (Click on the running man icon and paste the code into that window. Do not skip this step.)

 

Show us the SASLOG. (Click on the {i} icon and paste the log into that window. Do not skip this step.)

 

 

--
Paige Miller
AshleyBright
Obsidian | Level 7
%macro createDS(dsname, colnames, colvalues);

data &dsname;
attrib &colnames length = $1000;
infile datalines dlmstr='|';
input &colnames @@;
datalines;
&colvalues
;
run;

%mend createDS;

data test;
set raw;
call execute('%createDS('||dsn||','||columns||','||values||');');
run;
Astounding
PROC Star

Based on this program ...

 

get rid of @@.  It's not hurting anything, but it's not helping either.

 

Since you give your variables a length of $1000, I am tempted to think you might have some long values there ... values that might be affected by the number of characters that SAS will read.  So first, try this INFILE statement:

 

infile datalines dlm='|' dsd lrecl=9000;

 

That will let SAS read beyond the normal (256?) character limit when reading in data.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

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
  • 27 replies
  • 1571 views
  • 3 likes
  • 7 in conversation