SAS 嵌套 If 语句产生不正确的结果
SAS Nested If Statements Producing Incorrect Result
身份证号码6 returns 'Underweight' 当它应该 return 'Overweight'。
有问题的代码行,即第 30-53 行,包含嵌套的 if 语句并产生一个不希望的结果。这些行的目的是将样本划分为class权重class:体重不足、平均或体重过重。
TITLE 'A SHORT SAS PROGRAM';
OPTIONS LS=72;
* Create data file with height and weight data;
DATA HTWT;
INPUT ID GENDER $ HEIGHT WEIGHT;
DATALINES;
1 M 68.5 155.0
2 F 61.2 99.00
3 F 63.0 115.0
4 M 70.0 205.0
5 M 68.6 170.0
6 F 65.1 125.0
7 M 72.4 220.0
;
* Create a new categorical variable for height;
DATA HTWT;
SET work.HTWT;
IF HEIGHT < 68 THEN
STATURE='Short';
IF HEIGHT >=68 THEN
STATURE='Tall';
RUN;
* Create a new categorical variable for weight;
DATA HTWT;
SET work.HTWT;
IF GENDER='M' THEN
IF WEIGHT > 170 THEN
WEIGHT_CLASS='Overweight';
IF 170 >=WEIGHT >=150 THEN
WEIGHT_CLASS='Average';
IF WEIGHT < 140 THEN
WEIGHT_CLASS='Underweight';
ELSE IF GENDER='F' THEN
IF WEIGHT > 120 THEN
WEIGHT_CLASS='Overweight';
IF 120 >=WEIGHT >=100 THEN
WEIGHT_CLASS='Average';
IF WEIGHT < 100 THEN
WEIGHT_CLASS='Underweight';
RUN;
* Changing units of height from inches to centimeters;
DATA HTWT;
SET work.HTWT;
HEIGHT=2.54 * HEIGHT;
RUN;
* Creates HEALTH_INDEX;
DATA HTWT;
SET work.HTWT;
HEALTH_INDEX=WEIGHT/HEIGHT;
RUN;
* Print the data file HTWT;
PROC PRINT DATA=HTWT;
TITLE 'HEIGHT AND WEIGHT DATA';
RUN;
* Sorts the data by gender. Some procedures require sorted data;
PROC SORT DATA=HTWT OUT=sorted;
BY GENDER;
RUN;
* Print the sorted data file;
PROC PRINT DATA=sorted;
TITLE 'GENDER SORTED HTWT DATA';
RUN;
将嵌套的 if 语句修改为:
IF GENDER='M' THEN do;
IF WEIGHT > 170 THEN
WEIGHT_CLASS='Overweight';
else if 150 <= Weight <= 170 THEN
WEIGHT_CLASS='Average';
else
WEIGHT_CLASS='Underweight';
end;
else do;
IF WEIGHT > 120 THEN
WEIGHT_CLASS='Overweight';
else iF 100 <= Weight =< 120 THEN
WEIGHT_CLASS='Average';
else
WEIGHT_CLASS='Underweight';
end;
看看有没有效果?
连续的IF语句按顺序处理。因此,由于最后一个正在测试 WEIGHT 是否 < 100,那么当然 6 号被列为体重不足。
如果你想控制执行顺序,添加一些 ELSE and/or DO/END 块。您的基本结构可能应该如下所示。
if A then do;
if B then xxx ;
else if C then xxx ;
else if D then xxxx ;
end;
请不要接受我的答案是正确的,因为我来晚了,而之前的答案清晰有用。
但我在这里给你一个简单的建议,当你必须连接很多嵌套的 if 语句时,请使用 select when 语句(来自 sql 语言)给所有可能的层变量的值。
data want;
set have;
if gender='M' then do;
select (weight);
when (>x) weight_class='';
when (<y) weight_class='';
otherwise weight_class=''
end;
end;
else if gender='F' then do;
select (weight);
when (>x) weight_class='';
when (<y) weight_class='';
otherwise weight_class=''
end;
end;
run;
If 语句很有用,但有时创建格式并使用 put 语句进行赋值会更安全。如果您必须执行大量 IF,则尤其如此,因为至少在我的情况下,我输入的内容越多,我搞砸的机会就越大。
使用 put 语句的代码更容易检查和维护。
身份证号码6 returns 'Underweight' 当它应该 return 'Overweight'。 有问题的代码行,即第 30-53 行,包含嵌套的 if 语句并产生一个不希望的结果。这些行的目的是将样本划分为class权重class:体重不足、平均或体重过重。
TITLE 'A SHORT SAS PROGRAM';
OPTIONS LS=72;
* Create data file with height and weight data;
DATA HTWT;
INPUT ID GENDER $ HEIGHT WEIGHT;
DATALINES;
1 M 68.5 155.0
2 F 61.2 99.00
3 F 63.0 115.0
4 M 70.0 205.0
5 M 68.6 170.0
6 F 65.1 125.0
7 M 72.4 220.0
;
* Create a new categorical variable for height;
DATA HTWT;
SET work.HTWT;
IF HEIGHT < 68 THEN
STATURE='Short';
IF HEIGHT >=68 THEN
STATURE='Tall';
RUN;
* Create a new categorical variable for weight;
DATA HTWT;
SET work.HTWT;
IF GENDER='M' THEN
IF WEIGHT > 170 THEN
WEIGHT_CLASS='Overweight';
IF 170 >=WEIGHT >=150 THEN
WEIGHT_CLASS='Average';
IF WEIGHT < 140 THEN
WEIGHT_CLASS='Underweight';
ELSE IF GENDER='F' THEN
IF WEIGHT > 120 THEN
WEIGHT_CLASS='Overweight';
IF 120 >=WEIGHT >=100 THEN
WEIGHT_CLASS='Average';
IF WEIGHT < 100 THEN
WEIGHT_CLASS='Underweight';
RUN;
* Changing units of height from inches to centimeters;
DATA HTWT;
SET work.HTWT;
HEIGHT=2.54 * HEIGHT;
RUN;
* Creates HEALTH_INDEX;
DATA HTWT;
SET work.HTWT;
HEALTH_INDEX=WEIGHT/HEIGHT;
RUN;
* Print the data file HTWT;
PROC PRINT DATA=HTWT;
TITLE 'HEIGHT AND WEIGHT DATA';
RUN;
* Sorts the data by gender. Some procedures require sorted data;
PROC SORT DATA=HTWT OUT=sorted;
BY GENDER;
RUN;
* Print the sorted data file;
PROC PRINT DATA=sorted;
TITLE 'GENDER SORTED HTWT DATA';
RUN;
将嵌套的 if 语句修改为:
IF GENDER='M' THEN do;
IF WEIGHT > 170 THEN
WEIGHT_CLASS='Overweight';
else if 150 <= Weight <= 170 THEN
WEIGHT_CLASS='Average';
else
WEIGHT_CLASS='Underweight';
end;
else do;
IF WEIGHT > 120 THEN
WEIGHT_CLASS='Overweight';
else iF 100 <= Weight =< 120 THEN
WEIGHT_CLASS='Average';
else
WEIGHT_CLASS='Underweight';
end;
看看有没有效果?
连续的IF语句按顺序处理。因此,由于最后一个正在测试 WEIGHT 是否 < 100,那么当然 6 号被列为体重不足。 如果你想控制执行顺序,添加一些 ELSE and/or DO/END 块。您的基本结构可能应该如下所示。
if A then do;
if B then xxx ;
else if C then xxx ;
else if D then xxxx ;
end;
请不要接受我的答案是正确的,因为我来晚了,而之前的答案清晰有用。 但我在这里给你一个简单的建议,当你必须连接很多嵌套的 if 语句时,请使用 select when 语句(来自 sql 语言)给所有可能的层变量的值。
data want;
set have;
if gender='M' then do;
select (weight);
when (>x) weight_class='';
when (<y) weight_class='';
otherwise weight_class=''
end;
end;
else if gender='F' then do;
select (weight);
when (>x) weight_class='';
when (<y) weight_class='';
otherwise weight_class=''
end;
end;
run;
If 语句很有用,但有时创建格式并使用 put 语句进行赋值会更安全。如果您必须执行大量 IF,则尤其如此,因为至少在我的情况下,我输入的内容越多,我搞砸的机会就越大。
使用 put 语句的代码更容易检查和维护。