SAS在数据步骤中将字符转换为数字

时间:2017-10-05 16:58:31

标签: sas

我无法弄清楚为什么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;

谢谢你, 布赖恩

3 个答案:

答案 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;