SAS`select`……`when`基于范围
我有一些代码块,如果一个固定变量落在一个特定的范围内,比如SAS`select`……`when`基于范围,select,if-statement,sas,Select,If Statement,Sas,我有一些代码块,如果一个固定变量落在一个特定的范围内,比如 IF attained_age > 84 AND attained_age < 90 then do; /* block 1*/ end; ELSE IF attained_age > 89 AND attained_age < 95 then do; /* block 2*/ end; ELSE IF attained_age > 94 then
IF attained_age > 84 AND attained_age < 90 then
do;
/* block 1*/
end;
ELSE IF attained_age > 89 AND attained_age < 95 then
do;
/* block 2*/
end;
ELSE IF attained_age > 94 then
do;
/* block 3*/
end;
或
我可以为
sev_alpha
做一个例子,尽管这可以推广到其他两个例子。不幸的是,我无法测试这段代码,因为我本周不在办公室(和SAS许可证),但这应该可以正常工作
有一种方法可以使用PROC格式
,为这种类型的用例服务。首先,编写PROC格式
,如下所示:
PROC FORMAT;
VALUE fmt_alpha
84 <- 90 = "&UFLIC_LM_84_90_Alpha"
90 <- 95 = "&UFLIC_LM_90_95_Alpha"
95 - high = "&UFLIC_LM_95_Plus_Alpha"
;
RUN;
在本例中,=
,和high
表示最大数值。要处理其他两个变量,只需在PROC FORMAT
中再添加两个相应的VALUE
块,然后使用类似的PUT()
调用来设置变量
可以找到一些以这种方式使用
PROC格式的好文档。基本上,这是我从数字变量创建分类变量的常用方法,它通常比多个if/else
子句执行得更快。再次表示歉意,我今天无法测试这一点,但它至少接近解决方案。我可以为sev_alpha
做一个例子,尽管这可以推广到其他两个例子。不幸的是,我无法测试这段代码,因为我本周不在办公室(和SAS许可证),但这应该可以正常工作
有一种方法可以使用PROC格式
,为这种类型的用例服务。首先,编写PROC格式
,如下所示:
PROC FORMAT;
VALUE fmt_alpha
84 <- 90 = "&UFLIC_LM_84_90_Alpha"
90 <- 95 = "&UFLIC_LM_90_95_Alpha"
95 - high = "&UFLIC_LM_95_Plus_Alpha"
;
RUN;
在本例中,=
,和high
表示最大数值。要处理其他两个变量,只需在PROC FORMAT
中再添加两个相应的VALUE
块,然后使用类似的PUT()
调用来设置变量
可以找到一些以这种方式使用PROC格式的好文档。基本上,这是我从数字变量创建分类变量的常用方法,它通常比多个if/else
子句执行得更快。再次表示歉意,我今天无法对此进行测试,但它至少接近解决方案。我认为有两种简单的方法可以做到这一点,具体取决于您的复杂性
核心概念是使用symget
获取宏变量的值。这允许您在数据步骤中构造宏变量引用,否则您无法这样做。我更喜欢这种方式,而不是像sparc_spread那样将宏引用存储为proc格式
,如果有原因,该值实际上位于宏变量中。(如果没有,则跳过变量步骤,仅将宏变量中存储的值存储在proc format引用中。)
这也允许您轻松地编译一组引用;您不必为每个变量设置一组单独的格式,或者类似的内容,只需一个。(我想这就是sparc_spread对这个答案的评论。)
这可以与proc format
相结合,或者如果这更有意义,也可以只在数据步骤中完成-例如,如果您的范围都是5组,则只需进行数学运算即可得出值
以下是两者的一个示例:
%let lim_90_94=9094;
%let lim_95=95+;
%let lim_85_89=8589;
proc format;
value agef
85-89='85_89'
90-94='90_94'
95-high='95'
other ='NONE';
quit;
data have;
input age;
datalines;
88
92
96
;;;;
run;
data want;
set have;
val_a = symget(cats('lim_',put(age,agef.)));
val_b = symget(cats('lim_',
floor(age/5)*5,
ifc(age>95,'',(cats(
'_',
ceil(age/5)*5-1)))));
put age= val_a= val_b=;
run;
我认为有两种简单的方法可以做到这一点,具体取决于您的复杂性
核心概念是使用symget
获取宏变量的值。这允许您在数据步骤中构造宏变量引用,否则您无法这样做。我更喜欢这种方式,而不是像sparc_spread那样将宏引用存储为proc格式
,如果有原因,该值实际上位于宏变量中。(如果没有,则跳过变量步骤,仅将宏变量中存储的值存储在proc format引用中。)
这也允许您轻松地编译一组引用;您不必为每个变量设置一组单独的格式,或者类似的内容,只需一个。(我想这就是sparc_spread对这个答案的评论。)
这可以与proc format
相结合,或者如果这更有意义,也可以只在数据步骤中完成-例如,如果您的范围都是5组,则只需进行数学运算即可得出值
以下是两者的一个示例:
%let lim_90_94=9094;
%let lim_95=95+;
%let lim_85_89=8589;
proc format;
value agef
85-89='85_89'
90-94='90_94'
95-high='95'
other ='NONE';
quit;
data have;
input age;
datalines;
88
92
96
;;;;
run;
data want;
set have;
val_a = symget(cats('lim_',put(age,agef.)));
val_b = symget(cats('lim_',
floor(age/5)*5,
ifc(age>95,'',(cats(
'_',
ceil(age/5)*5-1)))));
put age= val_a= val_b=;
run;
这些代码块是否只涉及设置变量?e、 g.对于84到90的情况,该块类似于aighted\u age\u cat=“从84岁到90岁?”?如果是这样,我有一个想法可以发布。@sparc\u spread yes,设置两个名称相似的变量,update这些代码块是否有可能只涉及设置一个变量?e、 g.对于84到90的情况,该块类似于aighted\u age\u cat=“从84岁到90岁?”?如果是这样,我有一个想法可以发布。@sparc_spread yes,设置两个具有类似名称的变量,将更新+1,谢谢。我能用这种方式构造一些字符串范围的值吗,然后用这个范围来放置所有3个变量的值调用symput(“UFLIC_LM|”| prefix | | | | | Alpha”,count)
或者类似的东西吗?是的,我想这可能是我应该在上面做的。也就是说,PROC FORMAT
和PUT()
仅用于产生前缀,然后您只需将该前缀前置到单词“_Alpha”、“_Sigma”或“_Theta”以设置3个变量中的每一个。这意味着只有一个值块,而不是三个。如果我有SAS访问权限,我会重写上面的答案,但我需要先测试它。无论如何,我认为你的想法是好的,会起作用。我喜欢这里的想法-我不喜欢把宏引用直接放在格式中,但在其他方面这似乎很有用。老实说,您可以跳过宏变量,并使用该格式存储各种值本身-这次实际上是在3个值语句中,但是
%let lim_90_94=9094;
%let lim_95=95+;
%let lim_85_89=8589;
proc format;
value agef
85-89='85_89'
90-94='90_94'
95-high='95'
other ='NONE';
quit;
data have;
input age;
datalines;
88
92
96
;;;;
run;
data want;
set have;
val_a = symget(cats('lim_',put(age,agef.)));
val_b = symget(cats('lim_',
floor(age/5)*5,
ifc(age>95,'',(cats(
'_',
ceil(age/5)*5-1)))));
put age= val_a= val_b=;
run;