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

Hi all, 

 

Today I want to exclude the stock in specific countries with ENAME contains some characters, my code is as below:

data filter_each_country;
 set concatenate_;
  array delwords1 {18} $ 15 _temporary_ ('PN' 'PNA' 'PNB' 'PNC' 'PND' 'PNE' 'PNF'
'PNG' 'RCSA' 'RCTB' 'PNDEAD' 'PNADEAD' 'PNBDEAD' 'PNCDEAD' 'PNDDEAD' 'PNEDEAD' 'PNFDEAD' 'PNGDEAD');
   do i= 1 to dim(delwords1);
    if GEOGN ='BRAZIL' and findw(ENAME,delwords1[i],'','eir') >0 then delete;
   end;

  array delwords2 {3} $ 15 _temporary_ ('PFCL' 'PRIVILEGIADAS' 'PRVLG');
   do i= 1 to dim(delwords2);
    if GEOGN ='COLOMBIA' and findw(ENAME,delwords2[i],'','eir') >0 then delete;
   end;
 run;

The code is built based on my understanding: the code above runs through the first whole loop and delete the observation satisfying both conditions: having GEOGN='BRAZIL' and ENAME contains the words in array delwords1. Afterwards, SAS will start from observation 1 and run through the whole second loop and delete the observation satisfying both conditions: having GEOGN='COLOMBIA' and ENAME contains the words in array delwords2.

 

I am wondering if I fall into any fallacy.

 

Thank you and warm regards.

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
1 ACCEPTED SOLUTION

Accepted Solutions
ChrisNZ
Tourmaline | Level 20

Not exactly.

SAS will read observation 1 and assess whether it should be deleted, using all the tests you have programmed. Then it goes to obs 2 and does the same. It never goes back to obs 1.

View solution in original post

10 REPLIES 10
ChrisNZ
Tourmaline | Level 20

Not exactly.

SAS will read observation 1 and assess whether it should be deleted, using all the tests you have programmed. Then it goes to obs 2 and does the same. It never goes back to obs 1.

Phil_NZ
Barite | Level 11

Hi @ChrisNZ 

 

So, you mean that the first observation will go through all the loops until being deleted, if not it will be read implicitly (if there is no explicit output) at the end, and then the second observation will follow the same pattern.

 

Warm regards.

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
ChrisNZ
Tourmaline | Level 20

> So, you mean that the first observation will go through all the loops until being deleted, if not it will be read implicitly (if there is no explicit output) at the end, and then the second observation will follow the same pattern.

 

Rather: the first observation will go through all the loops until being deleted, if not it will be written out implicitly (if there is no explicit output) at the end, and then the second observation will follow the same pattern.

ChrisNZ
Tourmaline | Level 20

Note that you can improve speed a bit by using modifiers eit instead or eir.

 

 

japelin
Rhodochrosite | Level 12

I don't know what you are wondering about, is there a problem?
Also, I don't know what the value of ENAME is, but it looks like it could be rewritten like this, what do you think?

 

data filter_each_country;
  set concatenate_;
  array delwords1 {18} $ 15 _temporary_ ('PN' 'PNA' 'PNB' 'PNC' 'PND' 'PNE' 'PNF' 'PNG' 'RCSA' 'RCTB' 'PNDEAD' 'PNADEAD' 'PNBDEAD' 'PNCDEAD' 'PNDDEAD' 'PNEDEAD' 'PNFDEAD' 'PNGDEAD');
  array delwords2 {3} $ 15 _temporary_ ('PFCL' 'PRIVILEGIADAS' 'PRVLG');
  if (GEOGN ='BRAZIL'   and upcase(ENAME) in delwords1) or
     (GEOGN ='COLOMBIA' and upcase(ENAME) in delwords2) then delete;
 run;

This code does not use a do loop on the array, but uses in operator.
Since in operator detects word matches, it is not exactly the same as the findw function,

but since the array was set with duplicate characters such as "PN", "PNA", etc., I decided that it would be possible.
I hope this helps.

 

ChrisNZ
Tourmaline | Level 20

That's not the same thing at all.  findw() looks for a partial match, while your second test using upcase() looks for a full match of the string.

 

I was saying that modifier eit trims all strings in the expression, thus making the search for a match faster then simply using eir

 

 

 

Phil_NZ
Barite | Level 11

Hi @ChrisNZ 

 

Thank you very much for your introduction about "eit", I did a search from google and lexjansen but no document available for me to read about that, could you please suggest me a document or else?

 

Best regards.

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
ChrisNZ
Tourmaline | Level 20

> Thank you very much for your introduction about "eit", 

Look at the t modifier for function findw()

Phil_NZ
Barite | Level 11

Hi @japelin 

Thank you for your reply, the ENAME is as below (I show the deleted items)

TYPE	ENAME
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
772941	STOCKMANN AF DEAD 04/01/93 USE 946148
50879M	GMA HOLDINGS PDR
50879M	GMA HOLDINGS PDR
50879M	GMA HOLDINGS PDR
50879M	GMA HOLDINGS PDR
50879M	GMA HOLDINGS PDR
50879M	GMA HOLDINGS PDR
50879M	GMA HOLDINGS PDR
50879M	GMA HOLDINGS PDR
50879M	GMA HOLDINGS PDR
50879M	GMA HOLDINGS PDR

based on the filtered code:

data concatenate_ ;
	set work.concatenatex;
	where indc3 not in ('NA' 'UNCLS' 'UQEQS' 'OTHEQ');

	if (GEOGN ='PHILIPPINES' and findw(ENAME,'PDR','','eir') >0)
		or
		(GEOGN ='FINLAND' and findw(ENAME,'USE','','eir') >0)
		or
		(GEOGN ='NEWZEALAND' and findw(ENAME,'RTS','','eir') >0) then
		DELETE;
run;

Warm regards,

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
japelin
Rhodochrosite | Level 12

@Phil_NZ 

It is hard to say without checking what the value to be deleted looks like.

If it "contains a word" specified in the array, then you need findw, and if it "matches a character" specified in the array, then you can use in operator.

 

Let's take the case of "GEOGN ='COLOMBIA'" as an example.
If the value of ENAME is "PFCL XXX", findw will return >0, but in operator will return false.
If the value of ENAME is "PFCL", findw will return >0, and in operator will return true, so it can be rewritten.

 

Also, please don't multi-post.

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 10 replies
  • 1053 views
  • 7 likes
  • 3 in conversation