Question

I have this problem, but in SAS. To use the example provided in this question, I have 5 columns of names (name_1, name_2, etc.), and want to output a list in which the names are listed in descending order of frequency:

John     502
Robert   388
William  387
...
...       1

I took the answer to the question referenced above, and surrounded it with "proc sql;" and "quit;":

proc sql;
create table freqs as
SELECT name, COUNT(1)
FROM (           SELECT name_1 AS name FROM mytable
     UNION ALL SELECT name_2 AS name FROM mytable
     UNION ALL SELECT name_3 AS name FROM mytable
     UNION ALL SELECT name_4 AS name FROM mytable
     UNION ALL SELECT name_5 AS name FROM mytable
   ) AS myunion
 GROUP BY name
 ORDER BY COUNT(1) DESC
;
quit;

but am getting:

ERROR: Summary functions are restricted to the SELECT and HAVING clauses only.

I am using SAS 9.2.

Thoughts? Thanks for the help!

Était-ce utile?

La solution

You just need to change your ORDER BY expression to reference the second column. I'd also suggest that you assign the COUNT expression result to a SAS variable name (perhaps "freq"):

proc sql; 
   create table freqs as 
   SELECT name
        , COUNT(*) as freq
   FROM (
      SELECT           name_1 AS name FROM mytable
      UNION ALL SELECT name_2 AS name FROM mytable
      UNION ALL SELECT name_3 AS name FROM mytable
      UNION ALL SELECT name_4 AS name FROM mytable
      UNION ALL SELECT name_5 AS name FROM mytable
      ) AS myunion  
   GROUP BY name
   ORDER BY freq DESC;
quit; 

FYI: You can also say ORDER BY 2 DESC to give a relative reference.

Autres conseils

Proc SQL does not allow the count(1) in the order by. Try this instead:

proc sql;
    create table freqs as
        SELECT name, COUNT(1) as freqs
        FROM (SELECT name_1 AS name FROM mytable UNION ALL
              SELECT name_2 AS name FROM mytable UNION ALL
              SELECT name_3 AS name FROM mytable UNION ALL
              SELECT name_4 AS name FROM mytable UNION ALL
              SELECT name_5 AS name FROM mytable
             ) AS myunion
         GROUP BY name
         ORDER BY 2 DESC ;
 quit;

I think it allows the column reference.

The following might work as well if the dataset is not too big:

data mytable;
 input (name1-name5) (: $17.) @@;
 cards;
 john henry bob jerry james gary bill john mark gabe
 ;
run;

proc sql;
select 'do name = '
||catq("A2SC", name1,name2,name3,name4,name5)
||'; output; end;' into : nlist separated by ' ' from mytable
 ;
quit;

data test;
&nlist
Run;

proc freq order = freq;
tables name;
run;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top