BookmarkSubscribeRSS Feed
emaguin
Quartz | Level 8

I define a 7-element array and put a value in one or more of the elements but never two of them. (Why you say. Because LEC16 (see code) by design never includes a value for i1=2 or 5.) I later drop those two elements. But, i get a warning that those two elements were never addressed and the elements are not dropped. I understand the warning as useful but why weren't the elements dropped? Here's the code for one of the arrays. The drop command that follows is just drop  LEC16_2 LEC16_5;

*	LEC_16;
    array vlec16{7} A3LEC16_1-A3LEC16_7;
	nlen=lengthn(LEC_16);
	if (nlen ge 1) then do;
	nlen=1+(nlen-1)/2;
    do i=1 to nlen;
	   i1=1+2*(i-1);
	   val=substr(LEC_16,i1,1);
       vlec16{input(val,BEST32.)}=1;
    end;
	end;



3 REPLIES 3
ballardw
Super User

You really should show the entire data step. You do not show a DROP statement or option anywhere, so can't address why not.

You don't actually show where Lec16_2 or Lec16_5 might be used. You do not create them, they are not shown in your array statement. Your Array has

A3LEC16_1-A3LEC16_7

Not Lec16_2 or Lec16_5. So you did you intent to reference A3Lec16_2????

emaguin
Quartz | Level 8
Thanks for your reply. My assumption of array x{3} x1-x3; is that three new variables are created, x1, x2, x3. That the execution of the array statement creates them, not that do i=1 to 3; x{i}=5; creates them. Furthermore, I just re-ran code block minus the drop statement and looked at the variable list in the file and those variables are in there.
The entire data step is about 190 lines long. It consists of those 11 lines repeated 16 times for LEC_1 to LEC_16 plus some comment lines. The drop is just a drop but here it is:
drop LEC_1 LEC_2 LEC_3 LEC_4 LEC_5 LEC_6 LEC_7 LEC_8 LEC_9 LEC_10
LEC_11 LEC_12 LEC_13 LEC_14 LEC_15 LEC_16 val i i1
LEC1_2 LEC1_5 LEC2_2 LEC2_5 LEC3_2 LEC3_5 LEC4_2 LEC4_5 LEC5_2 LEC5_5
LEC6_2 LEC6_5 LEC7_2 LEC7_5 LEC8_2 LEC8_5 LEC9_2 LEC9_5 LEC10_2 LEC10_5
LEC11_2 LEC11_5 LEC12_2 LEC12_5 LEC13_2 LEC13_5 LEC14_2 LEC14_5
LEC15_2 LEC15_5 LEC16_2 LEC16_5;

Background. LEC_(i) records responses to an all-the-apply type question. There are five possible values, 1,3,4,6,7, but because of the all-that-apply element, LEC_(i) may equal 3 but it may also equal 1,3,4,5,6,7. That little bit of code unpacks LEC_(i) and records the string values as numeric in their own variables: LEC(i)_1, LEC(i)_3, LEC(i)_4, LEC(i)_6, LEC(i)_7.
I could have said array vlec16{5} A3LEC15_1 A3LEC15_3 A3LEC15_4 A3LEC15_6 A3LEC15_7; but why?? It's simpler to do what I did and then not use two of the variables and then delete them. So what! Like I said, understand the warning. But why did sas not execute the statement? It was a warning not an error.
Gene Maguin


ballardw
Super User

@emaguin wrote:
I could have said array vlec16{5} A3LEC15_1 A3LEC15_3 A3LEC15_4 A3LEC15_6 A3LEC15_7; but why?? It's simpler to do what I did and then not use two of the variables and then delete them. So what! Like I said, understand the warning. But why did sas not execute the statement? It was a warning not an error.
Gene Maguin



Because you did not "drop" A3Lec15_2 (or A3Lec16_2) you said the problem was with Lec16_2. You are now using different variable names than shown in your previous code snippet (A3Lec15). Which is one reason I asked for the entire data step, to see what you may be creating during the data step, exactly what you are "dropping". I strongly suspect you didn't create the variables that you claimed to attempt to drop.

 

A couple of other ways to parse comma delimited string of values and get a 1 or 1/0 coded variable.

data example;
   infile datalines truncover;
   input string $15.;
   array v(7);
   do i=1 to countw(string,',');
      v[input(scan(string,i,','),f8.)]=1;
   end;
datalines;
1
1,3
3,4,7
1,3,7
1,3,4,6,7
;

/* or to do 1/0 coding*/
data example;
   infile datalines truncover;
   input string $15.;
   array v(7);
   do i=1 to 7;
      v[i]= index(string,put(i,f1.))>0;
   end;
datalines;
1
1,3
3,4,7
1,3,7
1,3,4,6,7
;


Scan can pull a specific position number of a value from a delimited string. The last parameter is a list of delimiters. Lots simpler than trying to use the length and an offset. Probably not needed but sometimes you  want to break up a string at different points and though it appropriate to include a specific delimiter in this example. The Index function returns a position in a string of a substring. SAS returns 1 for true or 0 for false with comparing the returned value from Index to > 0.

Index would not be appropriate for finding 1 if you might have values like 10, 11 or 101 though INDEXW or FINDW might.

 

I prefer 1/0 coded values for "any that apply" type questions because then a sum=total number of selections, mean=percentage of respondents that selected the choice.

 

BTW, 190 lines isn't particularly long for a data step.

SAS Innovate 2025: Register Today!

 

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 3 replies
  • 643 views
  • 0 likes
  • 2 in conversation