sas 计数不同组合的数量

sas count number of different combinations

我有一个数据集,其中包含有关某个机构的学生教育信息。 我想知道他们参加过多少种不同的学习项目组合。我有硕士和学士级别的信息,我想统计每个教育级别(硕士、学士)的不同学习课程的数量。

例如 person1 可以有:

Bachelor:
- study1
- study2 
- study3
- study3

Master:
- studyA
- studyA 

然后我想要学士级别的3个学习项目(study3不应该算两次),硕士级别的1个。 每个学习计划都有自己的行 - 所以在数据集中 person1 有 6 行。 我希望每人一行告诉每个教育级别的学习课程数量:

person   number_bachelor     number_master
person1  3                   1
....etc...

我试过这个:

proc sql;
create table  new as
select  distinct personid, name, 
count(study) as number_of_bach
from old
group by personid, edu_level, study;
quit;

但它并没有给我想要的东西。 这给了我两行 person1,变量 "number_of_bach".

中的值为 1 和 2

如何编辑此代码以获得我想要的结果?

这是你想要的吗?

DATA old; 
   INPUT personid edu_level $ study $;
   DATALINES; 
1 bachelor study1
1 bachelor study2
1 bachelor study3
1 bachelor study3
1 master studyA
1 master studyA
1 master studyB
; 

PROC SQL;
  CREATE TABLE new AS
  SELECT personid, edu_level, COUNT (DISTINCT study) AS num_bach
    FROM OLD
   GROUP BY personid, edu_level;
QUIT;

study 是您查询中所谓的聚合列(因为 COUNT 是一个聚合函数),因此不应包含在 GROUP BY-子句(否则您的查询也将按 'study' 分组并且计数将始终为 1.

如果你想每人一个,然后添加一个 PROC TRANSPOSE:

PROC transpose IN = new OUT = new2;
  BY personid;
  ID edu_level;
RUN;

(您也可以使用子查询和连接而不是转置创建更复杂的查询,只要您没有数百万行,TRANSPOSE 的开销无关紧要)

为了完整起见,这里有一个 SQL-only 解决方案来解决你的问题:

PROC SQL;
  CREATE TABLE new AS
  SELECT p.personid, b.num_bachelors, m.num_masters
            /* Select unique personids */
            FROM (SELECT DISTINCT personid 
                    FROM old) AS p
            /* Count number of bachelor-level courses */
            LEFT JOIN (SELECT personid, 
                              COUNT(DISTINCT study) AS num_bachelors 
                         FROM old WHERE edu_level = 'bachelor' 
                        GROUP BY personid) AS b on p.personid = b.personid
            /* Count number of master-level courses */
            LEFT JOIN (SELECT personid, 
                              COUNT(DISTINCT study) AS num_masters 
                         FROM old WHERE edu_level = 'master' 
                        GROUP BY personid) AS m on p.personid = m.personid;

QUIT;

代码:

data education;
input person $ level $ program $;
datalines;
person1 bachelor study1
person1 bachelor study2
person1 bachelor study3
person1 bachelor study3
person1 master study1
person2 bachelor study1
person2 master study2
person2 master study1 
;
run;

proc sort data = education nodupkey;
 by person level program;
run;

proc sql;
 select person, 
 sum(case when level eq 'bachelor' then 1 else 0 end) as num_bachelors,
 sum(case when level eq 'bachelor' then 1 else 0 end) as num_masters
 from education
 group by person;
quit;

工作:在这里,SORT 程序将消除重复记录(如果有)。然后 SQL 过程只能用于生成学士级别的程序的人明智计数以及硕士级别的程序计数。

输出:

person   num_bachelors    num_masters
person1              3              1
person2              1              2