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;