BookmarkSubscribeRSS Feed
Scottmeup
Calcite | Level 5

Hi, I'm trying to work out if it's possible to use arrays and loops to parse over or reference variables that don't end in a number?

 

My variable names would look something like

v1a v1b v1c x1 v2a v2b v2c x2 v3a v3b v3c x3

 

I'm interested in parsing over those variables starting with v with the use of arrays and loops but i'm having a bit of difficulty. This is completely incorrect as far as Sas is concerned. I can't even reference v[i]b.

array v[3] = v1a--v1c;
do i = 1 to 3;
    if v[i]b=1 or v[i]c=1 then output_variable=1;

end;

 

 

The other thought that came to me was to put the entire set of variables in an array, iterate over them and use vname() but I can't seem to get the proper understanding for how to make that work either. 

 

Should I suck it up and manually code the variable names, or is it  possible to parse over variables with this naming structure using arrays?

I'd really like to tackle this as dynamically as possible.

5 REPLIES 5
PeterClemmensen
Tourmaline | Level 20

I'm not sure what you want to do with the variables, but you can get a list of variables not ending with a number from a data set like this

 

data MyData;
input Var OtherVar Var1 Var2;
datalines;
1 2 3 4
run;

proc sql noprint;
select name into :vars separated by " " from dictionary.columns 
where memtype="DATA" and memname="MYDATA" and anydigit(strip(reverse(name))) ne 1;
quit;

%put &vars.;

 

You can then use &vars. to put the relevant variables in an array and loop over it like this

 

data testing(drop=i);
   set MyData;
   array SomeArray {*} &vars.;
   do i=1 to dim(SomeArray);
      SomeArray[i]=100;
   end;
run;

 

Quentin
Super User

Can you edit your question to show a few records of example data you HAVE, and also show the data you WANT? 

 

It's possible you could do what you want with a two-dimensional array.  Often if I am tempted to use a two-dimensional array, I take that as a sign that my data are poorly structured.  And I end up transposing the data into a format that will make it easier to work with.

 

That said, a two-dimensional array approach might look something like:

 

data have ;
  input id v1a v1b v1c x1 v2a v2b v2c x2 v3a v3b v3c x3 ;
  cards ;
1  1  2  3  4  5  6  7  8  9  10  11  12
2 10 20 30 40 50 60 70 80 90 100 110 120
3  0  1  0  0  0  0  0  0  0   0   0   0
4  0  0  0  0  0  0  1  0  0   0   0   0
;

data want ;
  set have ;

  array v{3,3} v: ; *a little risky, assumes v* variables are in right order ; 

  do i=1 to dim1(v) ;

    *debugging, just to show how two-dimensional array works ;
    do j=1 to dim2(v) ;
      put id= v{i,j}= ;
    end ; 

    *v{i,2} will be v1b when i=1, v2b when i=2 etc ;
    if v{i,2}=1 or v{i,3}=1 then output_variable=1 ;
  end ;

run ;

 

 

 

 

BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
art297
Opal | Level 21

Here is one way:

data have ;
  input id v1a v1b v1c x1 v2a v2b v2c x2 v3a v3b v3c x3 ;
  cards ;
1  1  2  3  4  5  6  7  8  9  10  11  12
2 0 1 1 40 0 1 0 80 1 1 1 120
3  0  1  0  0  0  0  0  0  0   0   0   0
4  0  0  0  0  0  0  1  0  0   0   0   0
;

data want ;
  set have ;

  array a_v{*} v1a--x3 ;
  array output_variable(3);
  
  do i=1 to 3;
    output_variable(i)=0;
  end;
  
  do i=1 to dim(a_v) ;
    if anydigit(strip(reverse(vname(a_v(i))))) ne 1 then do;
      if a_v(i) eq 1 then output_variable(input(compress(vname(a_v(i)),,'kd'),8.))=1;
    end;
  end;
run ;

Art, CEO, AnalystFinder.com

 

mkeintz
PROC Star

While I would use @PeterClemmensen's solution, leveraging the information in the sql-only dictionary table, it might be informative to consider a preliminary data step to do the same.  Use that data step to write an array declaration to a temporary file, which is subsequently %INCLUDEd in your final data step:

 

filename t temp;
data _null_;
  set have (obs=1);
  array candidates{*} v1a--x3;
  file t;

  put 'array myvars {*} ';
  do i=1 to dim(candidates);
    _name=vname(candidates{i});
    if not(anydigit(char(_name,length(_name)))) then put +1 _name @;
  end;
  put  ';';
run;


options source2;
data want;
  set have;
  %include tmp;

  do i=1 to dim(myvars);
    ** do your array element processing here **;
  end;
  
run;

 

The "options source2" tells SAS to print to the log all sas statements in the %included file.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
s_lassen
Meteorite | Level 14

One possibility is to use a two-dimensional array, and use a macro to generate the variable names in the correct order, e.g.:

%macro array_names(prefix,suffix1,suffix2);

  %local i j;

  %do i=1 %to %sysfunc(countw(&suffix1));

    %do j=1 %to %sysfunc(countw(&suffix2)); &prefix.%scan(&suffix1,&i)%scan(&suffix2,&j)%end;

    %end;

%mend;

 

data _null_;

  retain v1a 1 v1b 2 v1c 3 x1 99 v2a 4 v2b 5 v2c 6 x2 999 v3a 7 v3b 8 v3c 9 x3 0;

  array v(3,3) %array_names(v,1 2 3,a b c);

  do i=1 to 3;

    do j=1 to 3;

      put v(i,j);

      end;

    end;

run;

I suggest using a macro because that is a good way of making sure you get the right variable names in the right order. So, instead of v[1]b you use v[1,2] etc.

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!

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
  • 5 replies
  • 2340 views
  • 5 likes
  • 6 in conversation