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

Hello,

 

I'm trying to parse a column called LINE that is delimited by spaces(' ').

Example records:

somedata1 somedata2

somedata1 somedata2 somedata3

somedata1

somedate1 somedate2 somedate3 somedate4

 

The number of delimiters is unknown. To handle this I'm taking the max count of spaces:

 

proc sql noprint;
  select max(countc(LINE,' ')) + 1 into: nums
  from testdata;
quit;

 

 

I would like to create additional columns with a prefix of col_ for the max number of delimiters found in the LINE column. So far I have the following code but it's not quite working.

 

data test;
set mydata;

  %macro cols;
    %do i = 1 %to &nums;
      col_&i = scan(LINE, &nums, ' ');
    %end;

  %mend cols;

  %cols;
run;

I would expect the Test dataset to contain 4 additional columns called Col_1, Col_2, Col_3, and Col_4; each containing the delimited values from LINE.

Put another way:

Col_1 will contain the values equal to somedata1

Col_2 will contain the values equal to somedata2

Col_3 will contain the values equal to somedata3

Col_4 will contain the values equal to somedata4

 

The results are getting close to the requirements but I'm missing something; its not quite right. I havent coded in SAS in a few years beyond simple CRUD stuff and am quite rusty.

 

Appreciate any help with this, thanks!

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

No need to write a macro.  Just use an array. 

 

You can use the macro variable to set the dimension of the array. Instead of counting spaces count the actual number of terms.

proc sql noprint;
  select max(countw(LINE,' ')) into :nums trimmed
  from testdata;
quit;

Now use the macro variable to define the number of variables to create.  Make sure to tell SAS how LONG to make the variables.

data test;
  set testdata;
  array col_ [ &nums ] $50 ;
  do i=1 to countw(line,' ');
    col_[i] = scan(line,i,' ');
  end;
run;

View solution in original post

6 REPLIES 6
Kurt_Bremser
Super User

Try this:

data long;
set have;
n = _n_;
do i = 1 to countw(line);
  col = scan(line,i);
  output;
end;
keep n col;
run;

proc transpose data=long out=want (drop=_name_);
by n;
var col;
run;
Reeza
Super User
Do you have other columns you need to account for?
Ody
Quartz | Level 8 Ody
Quartz | Level 8
I do not
Astounding
PROC Star
Your SCAN function refers to &nums when it should be using &i.
Tom
Super User Tom
Super User

No need to write a macro.  Just use an array. 

 

You can use the macro variable to set the dimension of the array. Instead of counting spaces count the actual number of terms.

proc sql noprint;
  select max(countw(LINE,' ')) into :nums trimmed
  from testdata;
quit;

Now use the macro variable to define the number of variables to create.  Make sure to tell SAS how LONG to make the variables.

data test;
  set testdata;
  array col_ [ &nums ] $50 ;
  do i=1 to countw(line,' ');
    col_[i] = scan(line,i,' ');
  end;
run;
Ody
Quartz | Level 8 Ody
Quartz | Level 8

This is exactly what i was looking for!

 

I guess I had the right pieces/idea, even have a few tries using arrays but couldn't get it to work. I was struggling (for more time than i care to admit) on how to execute it.

 

Thank you and to everyone else that offered some insight!

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 1171 views
  • 4 likes
  • 5 in conversation