Sas 显示分类变量中的所有值

Sas 显示分类变量中的所有值,sas,Sas,为此,谷歌搜索一直很困难。我有两个分类变量,age和months,每个变量有7个级别。对于一些级别,例如age=7和month=7没有值,当我使用proc sql时,没有条目的交点不会显示,例如: age month value 1 1 4 2 1 12 3 1 5 .... 7 1 6 ... 1 7 8 ..

为此,谷歌搜索一直很困难。我有两个分类变量,
age
months
,每个变量有7个级别。对于一些级别,例如
age=7
month=7
没有值,当我使用
proc sql
时,没有条目的交点不会显示,例如:

    age   month value
     1       1    4
     2       1    12
     3       1    5
      ....
     7       1    6
     ...
     1       7    8
      ....
     5       7    44
     6       7    5 
     THIS LINE DOESNT SHOW
我想要什么

   age   month value
     1       1    4
     2       1    12
     3       1    5
      ....
     7       1    6
     ...
     1       7    8
      ....
     5       7    44
     6       7    5 
     7       7    0

这种情况在数据中发生过几次,最后的组没有值,因此它们不会显示,但我希望它们在以后的目的中首先显示一些示例数据:

data test;
do age=1 to 7;
    do month=1 to 12;
        value = ceil(10*ranuni(1));
        if ranuni(1) < .9 then
            output;
    end;
end;
run;

分类变量的组独立交叉需要对每个级别变量进行不同的选择,并与其他变量交叉连接,这形成了一个外壳,可以与原始数据保持连接。对于年龄*月份有多个项目的情况,您需要确定是否需要

  • 具有重复的年龄、月份和原始值的行
  • 具有不同年龄和月份的行
    • 聚合函数以汇总值,或
    • 值太多的指示

和一个微小的变化,标志着重复类交叉

proc format;
  value S_V_V .t = 'Too many source values'; /* single valued value */
quit;

proc sql;
  create table want2(label="Distinct class combos allowing only one contributor to value, or defaulting to zero when none")
  as
  select distinct
    allAges.age
  , allMonths.month
  , case 
      when count(*) = 1 then coalesce(have.value,0)
      else .t
    end as value format=S_V_V.
  , count(*) as dup_check
  from
    (select distinct age from have) as allAges
  cross join
    (select distinct month from have) as allMonths
  left join
    have
  on 
    have.age = allAges.age and have.month = allMonths.month
  group by
    allMonths.month, allAges.age
  order by 
    allMonths.month, allAges.age
  ;
quit;

这种类型的处理也可以在Proc TABLATE中使用CLASSDATA=选项来完成。

您有几个可用的选项,这两个选项似乎都是在创建主数据然后将其合并的前提下工作的。 另一种方法是使用PrelofMT和FORMATs或CLASSDATA选项

最后一个——但可能是最简单的,如果数据集中有所有月份和所有年龄,那么在PROC FREQ中使用稀疏选项。它创建所有可能的组合

proc freq data=have;
   table age*month /out = want SPARSE;
   weight value;
run;

美丽的。这在我的一个更简单的例子中起了作用,看起来扩展起来并不困难。非常感谢
proc format;
  value S_V_V .t = 'Too many source values'; /* single valued value */
quit;

proc sql;
  create table want2(label="Distinct class combos allowing only one contributor to value, or defaulting to zero when none")
  as
  select distinct
    allAges.age
  , allMonths.month
  , case 
      when count(*) = 1 then coalesce(have.value,0)
      else .t
    end as value format=S_V_V.
  , count(*) as dup_check
  from
    (select distinct age from have) as allAges
  cross join
    (select distinct month from have) as allMonths
  left join
    have
  on 
    have.age = allAges.age and have.month = allMonths.month
  group by
    allMonths.month, allAges.age
  order by 
    allMonths.month, allAges.age
  ;
quit;
proc freq data=have;
   table age*month /out = want SPARSE;
   weight value;
run;