Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sas 定义默认值_Sas - Fatal编程技术网

Sas 定义默认值

Sas 定义默认值,sas,Sas,我是一个新的SAS用户,我有一个小问题 我有一个很大的空表A,其中有100列,是我用一个简单的proc-sql创建的;创建表格 我还有一个表B,比如说40列,表C,55列。 我想将这两个表添加到表A中,基本上我想要一个包含100列的表,其中包含来自表B&C的数据,我使用Union命令来完成这项工作 因为我没有100个变量的值,所以我必须设置默认值。 假设我在表a中有一列名为滋养,在表B中有食物,在表C中没有等价物。我有这样的规则:“如果数据来自表B,那么value=xxx,如果来自表C,那么va

我是一个新的SAS用户,我有一个小问题

我有一个很大的空表A,其中有100列,是我用一个简单的
proc-sql创建的;创建表格

我还有一个表B,比如说40列,表C,55列。 我想将这两个表添加到表A中,基本上我想要一个包含100列的表,其中包含来自表B&C的数据,我使用Union命令来完成这项工作

因为我没有100个变量的值,所以我必须设置默认值。 假设我在表a中有一列名为滋养,在表B中有食物,在表C中没有等价物。我有这样的规则:“如果数据来自表B,那么value=xxx,如果来自表C,那么value=“DefaultValue”

我可以用R或python轻松地做到这一点,但我正在用sas挣扎

我正在使用SAS sql命令(Union命令)


如何设置默认值?(对于所有数据类型:字符、数字或日期我使用的是SAS sql命令)

SAS中的日期实际上只是数字值。通常应用日期格式使其可读

因此,您可以在默认情况下分配缺少的值,如下所示:

. as ColumnName
或任何类似的默认日期

'17NOV2017'd as ColumnName
SAS可以处理缺少的值

Proc FORMAT;
  value MissingN 
    . = 'N/A'
    .N = 'Special N/A different than regular N/A'  /* for .N */
  ;
  value $MissingC
    ' ' = 'N/A'
  ;
  value SillyChristmasStocking
    .C = 'Bad'
    .O = 'children'
    .A = 'get'
    .L = 'No toys'
  ;
使用特殊编码的值(如“NA”)来表示缺少值的情况可能会起作用,但可能会导致头痛和额外编码。建议阅读SAS帮助:“使用缺少的值”

数字(也包括日期)的默认SAS缺失值为句点

. as MyColumnName
SAS还有27个表示为。

.A as MyColumnName
...
.Z as MyColumnName
._ as MyColumnName
字符变量缺少的值是一个空格

' '
'' empty quote string also works
'    ' as does a longer empty string
经验法则:编码丢失的值时要保持一致

Proc FORMAT;
  value MissingN 
    . = 'N/A'
    .N = 'Special N/A different than regular N/A'  /* for .N */
  ;
  value $MissingC
    ' ' = 'N/A'
  ;
  value SillyChristmasStocking
    .C = 'Bad'
    .O = 'children'
    .A = 'get'
    .L = 'No toys'
  ;
可以使用“缺少选项”指定打印缺少的值时显示的字符

OPTIONS MISSING = '*'; * My special representation of missing for this report;
Proc PRINT data=myData;
run;
OPTIONS MISSING = '.'; * Restore to the default;
SAS自定义格式还可用于自定义为缺少的值打印的内容

Proc FORMAT;
  value MissingN 
    . = 'N/A'
    .N = 'Special N/A different than regular N/A'  /* for .N */
  ;
  value $MissingC
    ' ' = 'N/A'
  ;
  value SillyChristmasStocking
    .C = 'Bad'
    .O = 'children'
    .A = 'get'
    .L = 'No toys'
  ;
关键字后的标记可以是要用于格式名称的任何新的有效SAS名称

Proc PRINT data=myData;
  format myColumnName MissingN.;
  format name $MissingC.;
  format behaviour SillyChristmasStocking.;
run;
至于您的字符缺少值的情况,我将继续使用

您提到了UNION,这是SQL的一项功能。在SQL中,也会出现联接,可能比UNION更频繁。当联接和来自两个源列的值发生冲突时,您需要使用COALESCE()函数或CASE
语句来选择非缺失值。

我不建议在SAS使用过程中的任何时候使用
PROC SQL
中的
UNION
UNION
几乎总是不如简单的数据步骤或数据步骤视图

这是因为数据步骤可以无缝地处理不同表上的不同变量等问题。SAS非常适合垂直组合数据集;当数据集不相同时,SQL总是有点棘手

data c;
  set a b;
run;
无论
a
b
是否相同,只要
a
b
没有冲突的变量名(它们不在同一列中),都会运行该函数;如果是,只需使用
重命名
数据集选项来解决它

如果您按照上述操作,并且不使用union,您将自动获得这些日期的缺失值。

NFN:

数据步 堆叠数据的数据步方法是最简单的。使用SET堆叠数据,并使用数组处理应用默认值。例如:

data stacked_data;
  set
    TARGET_TEMPLATE (obs = 0)
    ONE
    TWO
  ;

  array allchar _character_;
  array allnum  _numeric_;
  array dates d1-d5;

  do over allchar; if missing(allchar) then allchar = '*UNKNOWN*'; end;
  do over allnum; if missing(allnum) then allnum = -995; end;
  do over dates; if missing(dates) then dates='01NOV1971'd; end;
run;
一个微妙的问题是,一个或两个中缺少的任何值都将替换为默认值

过程SQL 在Proc SQL中,您需要创建一个包含a的默认值的单行表。该表可以联接到B和C的并集。联接选择将涉及coalesce(),以便在列不是来自B或C时选择预定义的默认值

例如,假设您有一个空的(零行)、多列的目标表(A)作为模板:

data TARGET_TEMPLATE;
  length _n_ 8;
  length a1-a5 $25 d1-d5 4 x1-x20 y1-y20 z1-z20 p1-p20 q1-q20 r1-r20 8;
  call missing (of _all_);
  format d1-d5 yymmdd10.;
  stop;
run;
由于Proc SQL不提供默认约束的语法,您需要创建自己的默认值表。这可能是数据步骤中最简单的步骤:

data TARGET_DEFAULTS;
  if 0 then set TARGET_TEMPLATE (obs=0); * prep pdv to match TARGET;
  array allchar _character_ (1000 * '*UNKNOWN*');
  array allnum  _numeric_   (1000 * -995);
  array d d1-d5 (5 * '01NOV1971'd); * override the allnum array initialization;
  output;
  stop;
run;
下面是一些生成的演示数据,一个和两个,对应于您的B和C:

data ONE;
  if 0 then set TARGET_TEMPLATE (obs=0); * prep pdv of demo data to match TARGET;
  do _n_ = 1 to 100;
    array a a1 a3 a5;
    array num x: y: z:;
    array d d1 d2;
    do over a; a = catx (' ', 'ONE', _n_, _i_); end;
    do over num; num = 1000 + _n_ + _i_; end;
    retain foodate '01jan1975'd;
    do over d; d=foodate; foodate+1; end;
    output;
  end;
  keep a1 a3 a5 x: y: z: d1 d2; * keep the disparate columns that were populated;
run;

data TWO;
  if 0 then set TARGET_TEMPLATE (obs=0); * prep pdv of demo data to match TARGET;
  do _n_ = 1 to 200;
    array a a1 a2 a3;
    array num x5 y5 z5 p: q: r:;
    array d d1 d2;
    do over a; a = catx (' ', 'TWO', _n_, _i_); end;
    do over num; num = 20000 + _n_*10 + _i_; end;
    retain foodate '01jan1985'd;
    do over d; d=foodate; foodate+1; end;
    output;
  end;
  keep a1 a2 a3 x5 y5 z5 p: q: r:; * keep the disparate columns that were populated;
run;
A、B和C的堆叠是简单的SQL,但不会引入特定于目标的默认值:

proc sql noprint;

  * generic UNION stack with SAS missing values (space and dot) for cells
  * where ONE and TWO did not contribute any data;

  create table stacked_data as
    select * from  have_data_TEMPLATE   %*** empty template first ensures template column order and formats are honored in output data;
    outer union corresponding           %*** align by column name, do not remove duplicates;
    select * from ONE
    outer union corresponding 
    select * from TWO
  ;
将堆栈放入子查询时,可以将其与默认值联接。选择每列的目标默认值涉及检查DICTIONARY.COLUMNS并生成SQL源以选择堆栈和默认值的合并

proc sql noprint;
  * codegen select items ;
  select cat('coalesce(STACK.',trim(name),',DEFAULT.',trim(name),') as ',trim(name))
  into :coalesces separated by ','
  from DICTIONARY.COLUMNS
  where libname = 'WORK' and memname = 'HAVE_DATA_TEMPLATE' %* dictionary lib and mem name values are always uppercase;
  order by npos
  ; 

  create table stacked_data_with_defaults as
    select * from TARGET_TEMPLATE             %*** output honors template;
    outer union corresponding
    select 
      source
    , &coalesces                              %*** apply codegen;
    from 
    (
      select * from  WORK.have_data_TEMPLATE  %*** ensure fully columned sub-select that will align with coalesces;
      outer union corresponding
      select 'one' as source, * from ONE
      outer union corresponding 
      select 'two' as source, * from TWO
    ) as STACK
    join
      TARGET_DEFAULTS as DEFAULT
    on 1=1 
  ;
quit;

为什么要创建一个空数据集?它将用于什么?也许你想将它用作默认结构定义?如果是这样,并且你想将B和C堆叠起来,并将它们放入a定义的结构中,你可以这样编码

data want ;
  set a(obs=0) b c ;
run;
不确定使用默认值的目的是什么。如果希望以特殊方式显示缺少的值,是否可以使用格式

或者您可以创建默认值的代码,也许只%包含它或将逻辑包装到宏中

  startdate=coalesce(startdate,'01JAN2013'd);
  gender=coalescec(gender,'UNKNOWN');
data want ;
  set a(obs=0) b c ;
%include 'defaults.sas';
run;
然后你的小程序创建一个新的数据集,它看起来像a,并使用B和C中的数据,看起来像这样

  startdate=coalesce(startdate,'01JAN2013'd);
  gender=coalescec(gender,'UNKNOWN');
data want ;
  set a(obs=0) b c ;
%include 'defaults.sas';
run;
如果确实希望将记录聚合到某个大型数据集中,那么可能需要使用
PROC APPEND
在正确的结构中创建记录后添加这些记录

proc append data=want base=a ;
run;

我认为这个答案有点太深陷于缺少的值。他们只是想初始化一个日期值,可能是缺少的,或者可能是默认的日期值。我同意,这就是为什么我尝试将简短的答案放在顶部。如果OP self自称是新的,那很好,我会添加一些上下文或信息,新人们可以从中受益。谢谢r你的答案。我想我没有正确地表达我的帖子,所以我编辑了iTunes。SAS Proc SQL没有实现默认约束