我无法弄清楚为什么SAS在数据步骤中将某些字符变量转换为数字。我已经确认每个变量都是一个使用PROC CONTENTS长度为1的字符变量。下面是生成此问题的代码。我没有通过谷歌搜索找到任何有助于解决此问题的答案。
data graddist.graddist11;
set graddist.graddist10;
if (ACCT2301_FA16 | BIOL1106_FA16 | BIOL1107_FA16 | BIOL1306_FA16 |
BIOL2101_FA16 | BIOL2301_FA16 | CHEM1111_FA16 | CHEM1305_FA16 | CHEM1311_FA16 |
ECON2301_FA16 | ENGL1301_FA16 | ENGL1302_FA16 | ENGR1201_FA16 | GEOG1313_FA16 |
HIST1301_FA16 | HIST1302_FA16 | MARK3311_FA16 | MATH1314_FA16 | MATH2413_FA16 |
MATH2414_FA16 | PHIL2306_FA16 | POLS2305_FA16 | POLS2306_FA16 |
PSYC1301_FA16 | PSYC2320_FA16) in ('A','B','C','D','F','W','Q','I') then FA16courses_b=1;
else FA16courses_b=0;
谢谢你, 布赖恩
答案 0 :(得分:2)
不幸的是,in
运算符在SAS中的运行方式不同。它只将左侧的单个值与右侧的值列表进行比较。您的代码基本上首先评估in
语句左侧的所有内容并返回TRUE / FALSE值(在SAS中,这是一个数值,其中0 = FALSE,除0 = TRUE之外的任何值)。然后基本上说:
if (0) in ('A'....'I') then...
或
if (1) in ('A'....'I') then...
您需要以其他方式重写等效性测试,例如:
if ACCT2301_FA16 in ('A'....'I')
or BIOL1106_FA16 in ('A'....'I')
or ...
答案 1 :(得分:1)
正如罗伯特所说,你不能用一个等于查询的方式一次将多个变量与多个值进行比较。
使用长字符串执行此操作的方法是使用FINDC
。将所有内容连接成一个字符串,将您的查找连接成一个字符串,并进行比较; FINDC在(charlist)中查找任何字符。
data graddist10;
length ACCT2301_FA16 BIOL1106_FA16 BIOL1107_FA16 $1;
input
ACCT2301_FA16 $
BIOL1106_FA16 $
BIOL1107_FA16 $
;
datalines;
X Y Z
A A B
B A B
. . .
A X .
X . B
W Y A
;;;;
run;
data graddist11;
set graddist10;
if findc(catx('|',of ACCT2301_FA16 BIOL1106_FA16 BIOL1107_FA16),
('ABCDFWQI')) then FA16courses_b=1;
else FA16courses_b=0;
run;
答案 2 :(得分:0)
你犯了两个语法错误,但他们互相取消了,SAS认为你的陈述有效。首先,IN ()
运算符只能在左侧取一个值。其次,|
令牌表示逻辑or
,不用于分隔列表中的项目。
在变量名之间使用|
会导致SAS将左侧减少为单个值,因此您对IN
的使用在语法上是正确的。这也是为什么SAS注意到它已经将你的字符变量转换为数值,以便它们可以被评估为布尔逻辑。
目前尚不清楚用于测试这些多个值的逻辑是什么。
您可以使用verify()
功能。也许是这样的,但要注意所有的价值都缺失的时候。
FA16courses_b = 0 ^= verify(cats(of ACCT2301_FA16 BIOL1106_FA16 BIOL1107_FA16),'ABCDEQWI');
但循环变量并逐个测试它们可能更容易。因此,例如,您可以将目标变量设置为零,然后在其中一个变量满足条件时有条件地将其设置为1。
FA16courses_b=0;
array c ACCT2301_FA16 BIOL1106_FA16 BIOL1107_FA16 ;
do i=1 to dim(c) while (FA16courses_b=0);
if not indexc(c(i),'ABCDEQWI') then FA16courses_b=1;
end;