How stupid is it that SAS can't count non-missing character fields? Just insane, worthless software.
If you have a programming question please provide example input data and the expected result.
Show the code you tried and if you got an error show the log with the code and error.
If you did not get the expected result then show the result you got and explain why it is not what you wanted.
Have you tried using N on character variables? It works just fine, as does COUNT:
data class;
set sashelp.class;
if _N_ < 5 then name = '';
run;
proc sql;
select sum(not missing(name))
,n(name)
,count(name)
,count(*)
from class;
quit;
I think that what @toomanystepsint is referring to is what's available in the datastep. There is a CMISS function (counts the number of missing character values), but AFAIK not anything corresponding to the N function for numeric values:
119 data _null_; 120 length test1-test3 $1; 121 test2='a'; 122 nmiss=cmiss(of test1-test3); 123 n=n(of test1-test3); 124 put n= nmiss=; 125 run; NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column). 123:15 NOTE: Variable test1 is uninitialized. NOTE: Variable test3 is uninitialized. NOTE: Invalid numeric data, test2='a' , at line 123 column 15. n=0 nmiss=2 test1= test2=a test3= nmiss=2 n=0 _ERROR_=1 _N_=1 NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds
@toomanystepsint wrote:
How stupid is it that SAS can't count non-missing character fields? Just insane, worthless software.
Like with any other software there isn't always a ready-made function that does exactly what you want for a specific problem. There is always a way to get what you need by combining existing functions.
If there is a function "missing" that you really would want to use regularly then you can always use Proc FCMP and write your own custom function and store it permanently for reuse.
Well, of course SAS can count non-missing character variables, but you're right that there is no function provided for that purpose.
There is a SASware ballot item recommending this function be added. Would encourage you to upvote:
https://communities.sas.com/t5/SASware-Ballot-Ideas/Add-Character-Version-of-N-Function/idi-p/397120
Also this tech support note shows SAS agrees this is a gap:
https://support.sas.com/kb/46/235.html
But both the ballot item and the tech support note are several years old. So hard to know if adding this function is on a roadmap or not.
As Quentin points out, if you can count the number of missing values in a set of k variables (by using CMISS), then you automatically get the number of nonmissing values by subtracting that number from k.
Outside of the DATA step:
@toomanystepsint wrote:
How stupid is it that SAS can't count non-missing character fields? Just insane, worthless software.
How many "fields"? Length of each? If enough values might have to define a long enough value to hold a concatenated string instead of the inline call to catx below.
Replace "of _character" below with a comma separated list of variable names or even explicit strings.
data junk; set have; nstr= countw(catx('~',of _character_),'~'); run;
The "trick" is to have a single character that you know does not appear in the values so catx can place a single character between values so the Countw function can tell where each value ends. Since CATX removes leading and trailing blanks before inserting the delimiter value in the first position then no such delimiter is inserted when the value is all blanks or missing. So the delimited list has "words" or non-missing variable values.
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!
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.