【问题标题】:SAS converting character to numeric in data stepSAS在数据步骤中将字符转换为数字
【发布时间】:2017-10-06 04:01:28
【问题描述】:

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

谢谢, 布赖恩

【问题讨论】:

    标签: sas


    【解决方案1】:

    不幸的是,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 ...
    

    【讨论】:

    • 谢谢你,罗伯特。自从我上次编码以来已经有几年了,我忘记了这个语句是如何工作的。非常感谢。
    【解决方案2】:

    正如 Robert 所说,您不能使用一个等于查询同时将多个变量与多个值进行比较。

    使用长字符串的方法是使用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;
    

    【讨论】:

      【解决方案3】:

      您犯了两个语法错误,但它们相互抵消了,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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多