The CARDINALITY Procedure
Getting Started: CARDINALITY Procedure
Note: Input data must be in a CAS table that is accessible in your CAS session. You must refer to this table by using a two-level name. The first level must be a CAS engine libref, and the second level must be the table name. For more information, see the sections Using CAS Sessions and CAS Engine Librefs and Loading a SAS Data Set onto a CAS Server in Chapter 2, Shared Concepts.
This example uses the Iris data set as input to demonstrate how to use PROC CARDINALITY. The Iris data published by Fisher (1936) include the species of iris and the sepal length, sepal width, petal length, and petal width (which are measured in millimeters) on 50 iris specimens from each of three species: Iris setosa, I. versicolor, and I. virginica.
You can load the sashelp.iris data set into your CAS session by naming your CAS engine libref in the first statement of the following DATA step:
data mycas.iris;
set sashelp.iris;
run;
These statements assume that your CAS engine libref is named mycas, but you can substitute any appropriately defined CAS engine libref.
The following statements show the basic usage:
proc cardinality data=mycas.iris outcard=mycas.card
outdetails=mycas.details maxlevels=10;
run;
The DATA= option names mycas.iris as the input data table. Two output data tables are requested: the required OUTCARD= option requests that cardinality and summary information be stored in the mycas.card data table, and the OUTDETAILS= option requests that the levels found for each variable be stored in the mycas.details data table. The MAXLEVELS= option specifies 10 as the maximum number of levels to report.
The following statements produce the "Cardinality Output Data" table, shown in Figure 1. This table contains one row for each variable in the input data table. If you do not want to display all the variables in the input data table, you can use the VAR statement to specify which variables you want to display.
proc print data=mycas.card;
var _varname_ _type_ _cardinality_ _more_;
run;
Figure 1: Cardinality Output Data Table
| Obs | _VARNAME_ | _TYPE_ | _CARDINALITY_ | _MORE_ |
|---|---|---|---|---|
| 1 | Species | C | 3 | N |
| 2 | SepalLength | N | 10 | Y |
| 3 | SepalWidth | N | 10 | Y |
| 4 | PetalLength | N | 10 | Y |
| 5 | PetalWidth | N | 10 | Y |
Table 1 explains the columns in the "Cardinality Output Data Table." This example works with a simple subset of the variables in both the cardinality and details data tables.
Table 1: Variables from the Cardinality Data
| Name | Description |
|---|---|
| _VARNAME_ | Variable name |
| _TYPE_ | Variable type (N for numeric or C for character) |
| _CARDINALITY_ | Number of levels extracted (less than or equal to the value of the MAXLEVELS= option) |
| _MORE_ | Indication of more unreported levels (Y to indicate more levels or N to indicate no more levels) |
Figure 1 shows that the Species variable has _TYPE_ = C, indicating that it is a character variable; its _CARDINALITY_ value is 3, indicating that three levels (values) are reported in the details data; and _MORE_ = N, indicating that there are no unreported levels.
Figure 1 shows that the SepalLength variable is a numeric variable (_TYPE_ = N); its _CARDINALITY_ value is 10, indicating that 10 different values are reported; and _MORE_ = Y, indicating that there are still more levels that can be explored.
The following statements produce the details output data table, as shown in Figure 2:
data details;
set mycas.details;
where _varname_ in ('Species', 'SepalLength');
run;
proc print data=details;
var _VARNAME_ _INDEX_ _FREQ_ _RAWNUM_ _RAWCHAR_;
run;
Figure 2: Details Output Data Table
| Obs | _VARNAME_ | _INDEX_ | _FREQ_ | _RAWNUM_ | _RAWCHAR_ |
|---|---|---|---|---|---|
| 1 | Species | 1 | 50 | . | Setosa |
| 2 | Species | 2 | 50 | . | Versicolor |
| 3 | Species | 3 | 50 | . | Virginica |
| 4 | SepalLength | 1 | 1 | 43 | |
| 5 | SepalLength | 2 | 3 | 44 | |
| 6 | SepalLength | 3 | 1 | 45 | |
| 7 | SepalLength | 4 | 4 | 46 | |
| 8 | SepalLength | 5 | 2 | 47 | |
| 9 | SepalLength | 6 | 5 | 48 | |
| 10 | SepalLength | 7 | 6 | 49 | |
| 11 | SepalLength | 8 | 10 | 50 | |
| 12 | SepalLength | 9 | 9 | 51 | |
| 13 | SepalLength | 10 | 4 | 52 | |
| 14 | SepalLength | . | 105 | 52 |
Table 2 explains the columns in the details output data table.
Table 2: Variables from the Details Output Data Table
| Name | Description |
|---|---|
| _VARNAME_ | Variable name |
| _INDEX_ | Index of the level |
| _FREQ_ | Frequency of the level |
| _RAWNUM_ | Raw level of the variable if numeric |
| _RAWCHAR_ | Raw level of the variable if character |
The Species variable has three rows in the details data table, one row for each of the reported levels (the _CARDINALITY_ variable in the "Cardinality Output Data Table" has the value 3). Each of these rows has _FREQ_ = 50, and the _RAWCHAR_ values are reported for each level. There are no more unreported levels for the variable Species (_MORE_ = N); thus, no row has a missing value (.) in the _INDEX_ column for the Species variable.
The "Details Output Data Table" reports the top 10 levels of the SepalLength variable and shows that there are still as many as 105 unreported levels that are greater than 52. (For the SepalLength variable, _CARDINALITY_ = 10 and _MORE_ = Y in the "Cardinality Output Data Table.") Therefore, SepalLength occupies 11 rows in the details data table (10 reported levels and one additional level that describes the group of all unreported levels.) The _INDEX_ of the unreported group of levels for the SepalLength variable is missing, reminding you that many levels make up this group. Essentially, the last row lumps all the other SepalLength rows into one level that has a missing _INDEX_ value. So you see 10 levels in addition to the levels greater than 52, a total of 11 rows for the SepalLength variable. The last row, which includes a missing _INDEX_ value, contains enough information to run the procedure again with a WHERE clause to obtain the next set of details.