Sas 定义默认值
我是一个新的SAS用户,我有一个小问题 我有一个很大的空表A,其中有100列,是我用一个简单的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
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没有实现默认约束