创建新变量,结合其他三个变量,而不使用sas中的ifelse

时间:2018-01-23 14:25:26

标签: sas

我需要创建一个变量,它结合了三个变量agesexeagios。所有这些都位于sas表中,所有这些都是数字的。

在第一步中,我将它们转换为分类变量然后我建议使用compress函数来创建这个新变量:

data new;
set new;

attrib sexe format=$15.;
if sexe=1 then sexe="HOMME";
else if sexe=0 then sexe="FEMME";

attrib agios format=$15.;
if agios=0 then agios="NON_AGIOS";
else AGIOS="AGIOS";

attrib age format=$15.;
if (age<=0) and (age=>25) then age="a25";
if (age<=26) and (age=>40) then age="a40";
if (age<=41) and (age=>65) then age="a60";
if (age=>65) then age="a65";
new_variable=compress(agios||sexe||age);
run; 

  But I have an warnings repeted to all the concerned variables:
  

警告:变量agios已被定义为数字。

表中的变量没有任何变换。此外,相关变量agesexeagios的值会从表中消失。它开始是空的。

我该如何更正? 或者是否有其他建议在不使用ifelse的情况下创建新变量?

谢谢

2 个答案:

答案 0 :(得分:2)

这个问题就在这一行:

if agios=0 then agios="NON_AGIOS";

编译器将agios初始化为数字变量。然后,您无法为其指定字符值。解决此问题的一种方法是创建一个新变量(agios2),然后重命名它,例如:

data new;
set new(rename=(agios=agios2 sexe=sexe2 age=age2)); /* rename vars on input */

attrib sexe format=$15.;
if sexe2=1 then sexe="HOMME";
else if sexe2=0 then sexe="FEMME";

attrib agios format=$15.;
if agios2=0 then agios="NON_AGIOS"; /* reference the renamed variable */
else AGIOS="AGIOS";
drop agios2 age2 sexe2;             /* drop the renamed variables on output */

attrib age format=$15.;
if (age2<=0) and (age2=>25) then age="a25";
if (age2<=26) and (age2=>40) then age="a40";
if (age2<=41) and (age2=>65) then age="a60";
if (age2=>65) then age="a65";
new_variable=compress(agios||sexe||age);
run; 

答案 1 :(得分:1)

另一种方法是为每个变量创建一个带有(NOTSORTED)选项的排序格式。报告时使用这些格式。例如,在Proc TABULATE FORMAT语句和CLASS语句中使用选项order=formatted preloadfmt

您发布的代码中的年龄分类似乎不正确

if (age<=0) and (age=>25) then age="a25";

年龄值不能同时&lt; = 0和&gt; = 25。

当标记范围时,我建议使用与它们所代表的范围一致的值。例如,有时您使用标签中的端点值(a25,a40),有时使用中间点(a60)。该计划不一致。

以下是在Proc TABULATE中输出时将格式应用于原始数据的示例代码。

proc format;
  value sexe (notsorted)
    0 = 'HOMME'
    1 = 'FEMME'
  ;

  value agios (notsorted)
    0 = 'NON_AGIOS'
    1 = 'AGIOS'
  ;

  value age (notsorted)
     0< - 25 = 'a25'
    25< - 40 = 'a40'
    40< - 65 = 'a60' /* inconsistent labeling of range */
    65< - high = 'a65'
  ;

  * mock data;
  data have;
    do personid = 1 to 100;
      sexe = ranuni(123) < 0.40;
      agios = ranuni(123) > 0.65;
      age = floor(12 + 58 * ranuni(123));
      output;
    end;
  run;

  proc tabulate data=have;
    class sexe agios age / order=formatted preloadfmt;
    classlevel sexe agios age / style=[pretext='A0A0A0A0'x];
    format sexe sexe. agios agios. age age.;
    table
      ( sexe agios age ) 
    , N
    / nocellmerge
    ;
  run;

enter image description here

有时,使用格式化的值成为实际数据来创建新数据是合适的,尤其是在将数据传递给可能没有SAS和格式代码的其他用户时。

data ...;
  set ...;
  ...
  sexe_fv = put (sexe,sexe.);  * fv stands for formatted value;
  agios_fv = put (agios, agios.);
  age_fv = put (age, age.);
  ...
run;