楼主: 1369425067
8068 7

[问答] SAS if else if 与if else 的疑问 [推广有奖]

  • 0关注
  • 0粉丝

高中生

2%

还不是VIP/贵宾

-

威望
0
论坛币
5 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
87 点
帖子
10
精华
0
在线时间
33 小时
注册时间
2019-8-14
最后登录
2020-11-18

楼主
1369425067 发表于 2019-8-14 15:30:19 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
data test;
var="a";output;
var="a";output;
var="a";output;
var="f";output;
var="f";output;
var="f";output;
var="f";output;
var="b";output;
var="c";output;
var="c";output;
run;
图为我想生成的数据集。
Snipaste_2019-08-14_15-26-01.png


/*第一种方法直接写的if与else,其程序结果与我想要的结果一样,如图所示*/
data test1;
   set test;
   if var ne lag(var) then do;
        retain i;
        i=1;
   end;
   else i=i+1;
run;
/*第二种方法写的if else if ,其程序结果与方法一不同*/
data test3;
   set test;
   if var ne lag(var) then do;
        retain i;
        i=1;
   end;
   else if var = lag(var) then i=i+1;
run;
结果如下:
Snipaste_2019-08-14_15-29-44.png

请问大神们,为什么结果不一致?导致第二种结果的原因是什么?不胜感激!




二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:else ELS LSE output RETAIN SAS data步处理 data步

沙发
1369425067 发表于 2019-8-14 16:01:13
data test3;
   set test;
   if var ne lag(var) then do;
        retain i;
        i=1;
   end;
    if var = lag(var) then i=i+1;
run;
这一种也可以生成我想要的数据集,就搞不明白这几种之间的区别

藤椅
weroded 发表于 2019-8-14 17:59:50
有一种说法是当lag(x)=x 写在条件式中时,SAS是无法读取的,你可以再加一个变量var_lag=lag(var)来观察一下它的结果,会发现在第一个条件"if var ne lag(var)"下, lag是没有读取到上一个实参的。

板凳
迷途小书童12345 学生认证  发表于 2019-8-15 11:10:57
/*LAG返回的是上一次LAGE函数运行时的实参,即LAG(argument)=上一次LAG函数执行时的argument.*/
所以你把它放在第二个if语句里面的时候,它会把第二个值作为初始值,所以不是说If else和if else if 的问题,而是lag函数的使用

报纸
superguy333 发表于 2019-8-18 20:18:59
捕获.PNG
  1. data test4;
  2.     set test;
  3.         var_lag=lag(var);
  4.     if var ne lag(var) then do;
  5.          retain i ;
  6.                  i=1;
  7.                    retain j 0;
  8.     end;
  9. else if var = var_lag then  /*使用var_lag和lag(var)是有区别的
  10.                               变量var_lag不会改变指针指向
  11.                               而lag(var),会将指针拨到下一行
  12.                                i,j仍然保持前面retain的值,然后再计算加1;*/
  13.           do;
  14.           i=i+1;
  15.                   j=j+1;
  16.           end;
  17. run;
复制代码
已有 1 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
admin_kefu + 50 + 5 + 5 + 5 热心帮助其他会员

总评分: 论坛币 + 50  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

地板
superguy333 发表于 2019-8-18 20:24:57
  1. data test4;
  2.     set test;
  3.         var_lag=lag(var);
  4.     if var ne lag(var) then do;
  5.          retain i ;
  6.                  i=1;
  7.                    retain j 0;
  8.     end;
  9. else if var = var_lag then  /*使用var_lag和lag(var)是有区别的
  10.                               变量var_lag不会改变指针指向
  11.                               而lag(var),会将指针拨到下一行
  12.                                i,j仍然保持前面retain的值,然后再计算加1;*/
  13.           do;
  14.           i=i+1;
  15.                   j=j+1;
  16.           end;
  17. run;
复制代码
test4

7
superguy333 发表于 2019-8-18 21:13:54

原因分析

1369425067 发表于 2019-8-14 16:01
data test3;
   set test;
   if var ne lag(var) then do;
if else 语句 ,else 后第2次使用lag(var),第二次使用指针会自动+1,变量值不变后 再加1。
if 语句只使用1次。
或者不适用函数lag(var), 而使用变量lag_VAR=LAG(VAR);  ELSE IF var=lag_VAR;
  1. data test4;
  2.     set test;
  3.         var_lag=lag(var);
  4.     if var ne lag(var) then do;
  5.          retain i ;
  6.                  i=1;
  7.                    retain j 0;
  8.     end;
  9. else if var = var_lag then  /*使用var_lag和lag(var)是有区别的
  10.                               变量var_lag不会改变指针指向
  11.                               而lag(var),会将指针拨到下一行
  12.                                i,j仍然保持前面retain的值,然后再计算加1;*/
  13.           do;
  14.           i=i+1;
  15.                   j=j+1;
  16.           end;
  17. run;
复制代码
捕获.PNG

8
赵安豆 发表于 2024-8-23 11:30:04
你的疑问在于SAS程序中使用`if-else`和`if-else if`结构时,为何得到的结果不同。

在第一种方法中:
```sas
data test1;
  set test;
  if var ne lag(var) then do;
    retain i;
     i=1;
  end;
  else i=i+1;
run;
```
此段代码的逻辑是:如果当前行的`var`变量值与前一行的不同(即,遇到一个新的`var`值),则重置`i`为1;否则,增加`i`的值。这是因为SAS中的`else`语句是在前面的`if`条件不成立时才会执行。

在第二种方法中:
```sas
data test3;
  set test;
  if var ne lag(var) then do;
    retain i;
     i=1;
  end;
  else if var = lag(var) then i=i+1;
run;
```
这里的问题在于,`else if`语句在前一个`if`条件成立时将不会被检查。因此,在当前行的`var`变量值与前一行不同的情况下(即执行了`i=1;`),紧接着的`else if var = lag(var)`这个条件永远不会被执行到。

但是,你可能希望的是:
```sas
data test4;
  set test;
  retain i;
  if var ne lag(var) then do;
     i=1;
  end;
  else if var = lag(var) then i=i+1; /* 此处的else if实际上是不必要的,但被正确解释 */
run;
```
在这种情况下,你实际上不需要`if-else`结构中的额外嵌套。SAS会正确地执行第一个条件(如果当前行与前一行不同,则重置`i`),然后检查下一个逻辑(如果相同,则递增`i`)。然而,在你的代码中,由于使用了`do-end`块,`else if`语句的意图可能被误解。

在SAS中,更简洁且明确地达到你目的的方式是:
```sas
data test4;
  set test;
  retain i;
  if var ne lag(var) then do;
     i=1;
  end;
  else if var = lag(var) and missing(i) = 0 then /* 确保i已经被初始化 */
      i=i+1;
run;
```
但是,由于`else`已经包含了之后的条件(即当`var`与前一行相同时),更简单的写法是:
```sas
data test4;
  set test;
  retain i;
  if var ne lag(var) then do;
     i=1;
  end;
  else /* 如果var与前一行相同,并且i已经被初始化(即非缺失) */
      i=i+1; /* 直接递增i,无需再次检查var */
run;
```

此文本由CAIE学术大模型生成,添加下方二维码,优先体验功能试用



您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-20 17:42