/* Richard A. DeVenezia * www.devenezia.com * 2/11/04 */ data x; do k = 65 to 70; d = byte (k); output; end; run; %macro putHash (hash, vars); %let hi = hi_%substr(%sysfunc(ranuni(0),10.8),3); declare hiter &hi ("&hash"); do rc = &hi..first() by 0 while (rc = 0); put %sysfunc(translate(&vars,=,#)); rc = &hi..next(); end; &hi..delete(); put; %mend; options mprint; * HI.next() causes Read Access Violation if current key is deleted; data _null_; length k 8 d $1; declare hash H (dataset:'x', ordered:'a'); H.defineKey ('k'); H.defineData ('k', 'd'); H.defineDone (); call missing (k,d); declare hiter HI ('H'); * deleting key gone past is ok; put 'A will be deleted when iterator is a C'; do rc = HI.first() by 0 while (rc=0); put k= d=; if d = 'C' then do; k = 65; H.find(); H.remove(); end; rc = HI.next(); end; put; * delete key yet to be reached is ok (next or beyond); put 'D will be deleted when iterator is a C'; do rc = HI.first() by 0 while (rc=0); put k= d=; if d = 'C' then do; k = 68; H.find(); H.remove(); end; rc = HI.next(); end; put; * delete key iterator is at, * causes Read Access Violation at next(); put 'C will be deleted when iterator is a C'; do rc = HI.first() by 0 while (rc=0); put k= d=; if d = 'C' then do; rc_remove = H.remove(); put rc_find= rc_remove=; end; rc = HI.next(); put rc=; end; put; stop; run; data _null_; put 'This data step is ok'; length k 8 d $1; declare hash H (dataset:'x', ordered:'a'); H.defineKey ('k'); H.defineData ('k', 'd'); H.defineDone (); call missing (k,d); declare hiter HI ('H'); * replace data for key iterator is at; put 'C will be replaced with Z when iterator reaches C'; do rc_next = HI.first() by 0 while (rc_next=0); put k= d=; if d = 'C' then do; d = 'Z'; rc_replace = H.replace(); end; rc_next = HI.next(); end; put; do rc_next = HI.first() by 0 while (rc_next=0); put k= d=; rc_next = HI.next(); end; put; stop; run; data y; k = 0; d = .; output; do k = 1 to 5; d = k**2; output; end; run; data _null_; put 'This data step is NOT ok'; put 'H.replace(key:k, data:., data:.) construct converts missing (.) to zero (0)'; length k d 8 ; declare hash H (dataset:'y', ordered:'a'); H.defineKey ('k'); H.defineData ('k', 'd'); H.defineDone (); call missing (k,d); declare hiter HI ('H'); put 'replace numeric data with missing values using data:.'; do rc_next = HI.first() by 0 while (rc_next=0); rc_replace = H.replace(key:k, data:k, data:.); rc_next = HI.next(); end; put 'missings were changed into zeros!'; do rc_next = HI.first() by 0 while (rc_next=0); put k= d=; rc_next = HI.next(); end; put; put 'replace numeric data with missing values using variables'; do rc_next = HI.first() by 0 while (rc_next=0); d = .; rc_replace = H.replace(); rc_next = HI.next(); end; put 'missing stays missing'; do rc_next = HI.first() by 0 while (rc_next=0); put k= d=; rc_next = HI.next(); end; put; stop; run; data y; k = .; d = .M; output; k = 0; d = .; output; do k = 1 to 5; d = k**2; output; end; run; data _null_; length k d 8 ; declare hash H (dataset:'y', ordered:'a'); H.defineKey ('k'); H.defineData ('k', 'd'); H.defineDone (); call missing (k,d); declare hiter HI ('H'); put 'replace numeric data with missing values using data:.'; put '.M not changed to regular missing (or zero (incorrectly like other keys))'; do rc_next = HI.first() by 0 while (rc_next=0); rc_replace = H.replace(key:k, data:k, data:.); rc_next = HI.next(); end; do rc_next = HI.first() by 0 while (rc_next=0); put k= d=; rc_next = HI.next(); end; put; put 'replace numeric data with missing values using variables'; do rc_next = HI.first() by 0 while (rc_next=0); d = .; rc_replace = H.replace(); rc_next = HI.next(); end; put 'missing stays missing'; do rc_next = HI.first() by 0 while (rc_next=0); put k= d=; rc_next = HI.next(); end; put; run;