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

Hello,

What is the best solution for scanning a formula without getting in the output   -  c(I) columns (I = 1,2,3..)

a. Null values (for example in the available data we have C3 and C4 with null values)

b. Duplicate values (for example X1 appears twice in the second line of have data )
c. Digits (the digit 2 was dropped succesfully from available data )

Thanks.


Data Have ;
infile datalines dsd ;
input formula : $30. ;
datalines ;
X1 / X2 + X4
(X1 + X2) / (X3 - X1) * 2
;
Run ;

data Available ;
set Have ;
delims = '+-/*()' ;
Array ccc_ [10] $32 c1-c10 ;
do i = 1 to 10 ;
if countc(scan(formula, i, delims),'X') > 0
ccc_[i] = scan(formula, i, delims) ;
end ;
drop delims i ;
run ;

Data Want ;
infile datalines dsd ;
input C1 $3. C2 $3. C3 $3. ;
datalines ;
X1 X2 X4
X1 X2 X3
;
Run ;

1 ACCEPTED SOLUTION

Accepted Solutions
ErikLund_Jensen
Rhodochrosite | Level 12

Hi @J111 

 

The following should work. I had some trouble getting the sorting right until I noticed that some of the C1-C10 variables had leading blanks.

/*** Your code ***/

Data Have ;
  infile datalines dsd ;
  input formula : $30. ;
  datalines ;
X1 / X2 + X4
(X1 + X2) / (X3 - X1) * 2
;
Run ;

data Available ;
  set Have ;
  delims = '+-/*()' ;
  Array ccc_ [10] $32 c1-c10 ;
  do i = 1 to 10 ;
    if countc(scan(formula, i, delims),'X') > 0 then ccc_[i] = scan(formula, i, delims) ;
  end ;
  drop delims i ;
run ;

Data Want;
  infile datalines dsd ;
  input C1 $3. C2 $3. C3 $3. ;
  datalines ;
X1 X2 X4
X1 X2 X3
;
Run ;

/**** My solution ***/

* Set number of array elements;
data _null_;
  set available;
  array elements $ c:;
  call symputx('arrdim',dim(elements));
run;
%put &=arrdim;

data result (drop=c:);
  set available;
  array elements $ c:;
  array out $ O1-O%eval(&arrdim);

  * left align elements - to solve bug in input creation;
  do i = 1 to dim(elements);
    elements{i} = left(elements{i});
  end;

  call sortc (of elements{*});
  j = 0;
  do i = 1 to dim(elements);
    if elements{i} ne '' then do;
      if i = 1 then do;
        j = j + 1;
        out{j} = elements{i};
      end;
      else if elements{i} ne elements{i-1} then do;
        j = j + 1;
        out{j} = elements{i};
      end;
    end;
  end;
run;

 

 

View solution in original post

3 REPLIES 3
J111
Obsidian | Level 7

 

ops ... added "then" below

data Available ; set Have ; delims = '+-/*()' ; Array ccc_ [10] $32 c1-c10 ; do i = 1 to 10 ; if countc(scan(formula, i, delims),'X') > 0 then ccc_[i] = scan(formula, i, delims) ; end ; drop delims i ; run ; 

ErikLund_Jensen
Rhodochrosite | Level 12

Hi @J111 

 

The following should work. I had some trouble getting the sorting right until I noticed that some of the C1-C10 variables had leading blanks.

/*** Your code ***/

Data Have ;
  infile datalines dsd ;
  input formula : $30. ;
  datalines ;
X1 / X2 + X4
(X1 + X2) / (X3 - X1) * 2
;
Run ;

data Available ;
  set Have ;
  delims = '+-/*()' ;
  Array ccc_ [10] $32 c1-c10 ;
  do i = 1 to 10 ;
    if countc(scan(formula, i, delims),'X') > 0 then ccc_[i] = scan(formula, i, delims) ;
  end ;
  drop delims i ;
run ;

Data Want;
  infile datalines dsd ;
  input C1 $3. C2 $3. C3 $3. ;
  datalines ;
X1 X2 X4
X1 X2 X3
;
Run ;

/**** My solution ***/

* Set number of array elements;
data _null_;
  set available;
  array elements $ c:;
  call symputx('arrdim',dim(elements));
run;
%put &=arrdim;

data result (drop=c:);
  set available;
  array elements $ c:;
  array out $ O1-O%eval(&arrdim);

  * left align elements - to solve bug in input creation;
  do i = 1 to dim(elements);
    elements{i} = left(elements{i});
  end;

  call sortc (of elements{*});
  j = 0;
  do i = 1 to dim(elements);
    if elements{i} ne '' then do;
      if i = 1 then do;
        j = j + 1;
        out{j} = elements{i};
      end;
      else if elements{i} ne elements{i-1} then do;
        j = j + 1;
        out{j} = elements{i};
      end;
    end;
  end;
run;

 

 

Ksharp
Super User

If you have Y1 or Z2 ...........

 

Data Have ;
  infile datalines dsd ;
  input formula : $30. ;
  datalines ;
X1 / X2 + X4
(X1 + X2) / (X3 - X1) * 2
;
Run ;

data temp;
 set have;
 id+1;
 pid=prxparse('/[a-z]\d+/i');
 start=1;end=length(formula);
 call prxnext(pid,start,end,formula,p,l);
 do while(p>0);
  temp=substr(formula,p,l);
  output;
  call prxnext(pid,start,end,formula,p,l);
 end;
keep id temp;
run;
proc sort data=temp nodupkey;by id temp;run;
proc transpose data=temp out=want(drop=_:) prefix=C;
by id;
var temp;
run;

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
  • 3 replies
  • 401 views
  • 1 like
  • 3 in conversation