The script uses `PROC TEMPLATE` to create a new tagset. This tagset, 'counter', is designed to intercept ODS events. It uses an internal dictionary to store and increment the counter for each event name encountered. At the end of the document (`doc finish` event), it sorts the events in descending order of frequency and prints a simple text report. The script then demonstrates the use of this tagset by applying it to the output of `PROC PRINT` on the `sashelp.class` table, redirecting the counting report to a file 'counter.txt'.
Data Analysis
Type : SASHELP
The script uses the `sashelp.class` table as an example to generate ODS events. This table is not modified; it only serves to trigger the execution of a procedure (`PROC PRINT`) whose events will be counted by the tagset.
1 Code Block
PROC TEMPLATE
Explanation : This block uses `PROC TEMPLATE` to define a new ODS tagset called `counter`. Tagsets allow fine-grained control over SAS-generated output. This one is programmed to count the occurrences of each ODS event type. It uses dictionaries (similar to hash tables) to maintain the counts. Key events are `doc` (for initialization and finalization), `count` (to increment counters), `sort` (to sort results), and `report` (to display the final report).
Copied!
/*
Tagset to count the frequency of each event and print a report.
*/
proc template;
define tagset tagsets.counter;
default_event = 'count';
/*
Create an event count dictionary `$events'. Each key in the
dictionary is an event name. The value is the number of times the
event occurred.
At doc start, initialize the event dictionary and the total event
counter. At finish, sort the event names by decreasing occurrence
and print a report.
*/
define event doc;
start:
eval $events[event_name] 1;
eval $total 0;
finish:
trigger sort;
trigger report;
end;
define event count;
do / if $events[event_name];
eval $events[event_name] $events[event_name] + 1;
else;
eval $events[event_name] 1;
done;
eval $total $total+1;
end;
/*
Create an array `$evname' that contains the event names. Sort
`$evname' using the counts in `$events'.
*/
define event sort;
trigger dup;
eval $size $events; /* $size = size of $events */
eval $i $size;
do / while $i > 0;
eval $j 1;
do / while $j < $i;
eval $jplus1 $j+1;
set $evname_j $evname[$j];
set $evname_jplus1 $evname[$jplus1];
do / if $events[$evname_j] < $events[$evname_jplus1];
set $temp $evname[$j];
set $evname[$j] $evname[$jplus1];
set $evname[$jplus1] $temp;
done;
eval $j $j+1;
done;
eval $i $i-1;
done;
end;
define event dup;
iterate $events;
do / while _name_;
set $evname[] _name_;
next $events;
done;
end;
/*
Print the `$events' dictionary in the order specified by the
`$evname' array.
*/
define event report;
put "Number of individual events: " $events nl;
put "Total number of events: " $total nl nl;
put "Count Event name" nl;
iterate $evname;
do / while _value_;
eval $occur $events[_value_];
eval $occur putn($occur, 'F.', 5);
put $occur " " _value_ nl;
next $evname;
done;
end;
end;
run;
1
/*
2
Tagset to count the frequency of each event and print a report.
3
*/
4
5
PROC TEMPLATE;
6
define tagset tagsets.counter;
7
default_event = 'count';
8
9
/*
10
Create an event count dictionary `$events'. Each key in the
11
dictionary is an event name. The value is the number of times the
12
event occurred.
13
14
At doc start, initialize the event dictionary and the total event
15
counter. At finish, sort the event names by decreasing occurrence
16
and print a report.
17
*/
18
define event doc;
19
start:
20
eval $events[event_name] 1;
21
eval $total 0;
22
finish:
23
trigger sort;
24
trigger report;
25
END;
26
27
define event count;
28
DO / IF $events[event_name];
29
eval $events[event_name] $events[event_name] + 1;
30
ELSE;
31
eval $events[event_name] 1;
32
done;
33
eval $total $total+1;
34
END;
35
36
/*
37
Create an array `$evname' that contains the event names. Sort
38
`$evname' using the counts in `$events'.
39
*/
40
define event sort;
41
trigger dup;
42
eval $size $events; /* $size = size of $events */
43
eval $i $size;
44
DO / while $i > 0;
45
eval $j 1;
46
DO / while $j < $i;
47
eval $jplus1 $j+1;
48
SET $evname_j $evname[$j];
49
SET $evname_jplus1 $evname[$jplus1];
50
DO / IF $events[$evname_j] < $events[$evname_jplus1];
51
SET $temp $evname[$j];
52
SET $evname[$j] $evname[$jplus1];
53
SET $evname[$jplus1] $temp;
54
done;
55
eval $j $j+1;
56
done;
57
eval $i $i-1;
58
done;
59
END;
60
61
define event dup;
62
iterate $events;
63
DO / while _name_;
64
SET $evname[] _name_;
65
next $events;
66
done;
67
END;
68
69
/*
70
Print the `$events' dictionary in the order specified by the
71
`$evname' array.
72
*/
73
define event report;
74
put "Number of individual events: " $events nl;
75
put "Total number of events: " $total nl nl;
76
put "Count Event name" nl;
77
iterate $evname;
78
DO / while _value_;
79
eval $occur $events[_value_];
80
eval $occur putn($occur, 'F.', 5);
81
put $occur " " _value_ nl;
82
next $evname;
83
done;
84
END;
85
86
END;
87
88
RUN;
2 Code Block
PROC PRINT
Explanation : This block applies the previously defined `tagsets.counter` tagset. The ODS `listing` destination is closed, then the `counter` tagset is activated to write to the `counter.txt` file. The execution of `PROC PRINT` on `sashelp.class` generates events that are intercepted and counted by the tagset. Finally, the tagset is closed and the `listing` destination is reactivated.
This material is provided "as is" by We Are Cas. There are no warranties, expressed or implied, as to merchantability or fitness for a particular purpose regarding the materials or code contained herein. We Are Cas is not responsible for errors in this material as it now exists or will exist, nor does We Are Cas provide technical support for it.
SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. ® indicates USA registration. WeAreCAS is an independent community site and is not affiliated with SAS Institute Inc.
This site uses technical and analytical cookies to improve your experience.
Read more.