数据步骤中的SAS呼叫拥塞

时间:2019-02-05 15:13:23

标签: sas

我在使用sas数据步骤时遇到此问题。我的要求是获取变量列表,例如

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Structure", inversedBy="referent")
 */
private $structure;

public function getStructure(): ?Structure
{
    return $this->structure;
}

public function setStructure(?Structure $structure): self
{
    $this->structure = $structure;

    return $this;
}

但是我遇到了宏变量bal_mnth无法解析的错误。同样,一旦它确实运行成功,但是我希望输出必须按顺序打印,但是当total_jun2018 = sum(jun2018, dep_jun2018); total_jul2018 = sum(jul2018, dep_jul2018); 时它仅输出最后一个循环的输出,然后仅打印Data final4; set final3; by hh_no; do i=0 to &tot_bal_mnth.; bal_mnth = put(intnx('month',"&min_Completed_dt."d, i-1), monyy7.); call symputx('bal_mnth', bal_mnth); &bal_mnth._total=sum(&bal_mnth., Dep_&bal_mnth.); output; end;

任何帮助将不胜感激!

谢谢, 阿贾伊

3 个答案:

答案 0 :(得分:1)

这是学习SAS Macro时的常见问题。问题是,在首次提交数据步骤以执行时,宏处理器需要将&bal_mnth解析为一个值,但是在实际执行数据步骤之前,CALL SYMPUT不会执行,因此在您提交时代码,&bal_mnth没有可用的值。

在这种情况下,不需要在数据集中将bal_mnth创建为变量,因此可以将bal_mnth = put(intck(...))开头的行替换为%let bal_mnth = ...语句。 %let在提交数据步骤时执行,因此可以在需要时使用它的值。

我建议的%let语句将需要至少在一个SYSFUNC调用中包装函数,这留给读者练习:-)

答案 1 :(得分:1)

您似乎想生成一系列赋值语句,例如:

total_jun2018 = sum(jun2018, dep_jun2018); 
total_jul2018 = sum(jul2018, dep_jul2018);
...
total_jan2019 = sum(jan2019, dep_jan2019);

所谓的墙纸代码。

如果变量名称更简单,例如从dep1dep18,则可以使用数组来处理数据。根据您当前的命名约定,生成数组语句的问题与生成一系列赋值语句的问题没有太大不同。

您可以创建一个宏,以便可以使用%DO循环来生成墙纸代码。

%local i bal_mnth;
%do i=0 %to &tot_bal_mnth.;
  %let bal_mnth =  %sysfunc(intnx(month,"&min_Completed_dt."d, &i-1), monyy7.);
  total_&bal_mnth = sum(&bal_mnth , Dep_&bal_mnth );
%end;

或者您可以仅使用数据步骤将代码生成到文件中。

%let tot_bal_mnth = 7;
%let min_Completed_dt=01JUN2018;
filename code temp;
data _null_;
  file code;
  length bal_mnth $7 ;
  do i=0 to &tot_bal_mnth.;
    bal_mnth =  put(intnx('month',"&min_Completed_dt."d, i-1), monyy7.);
    put 'total_'  bal_mnth $7. ' = sum(' bal_mnth $7. ', Dep_' bal_mnth $7. ');';
  end;
run;

因此生成的代码文件如下所示:

total_MAY2018 = sum(MAY2018, Dep_MAY2018);
total_JUN2018 = sum(JUN2018, Dep_JUN2018);
total_JUL2018 = sum(JUL2018, Dep_JUL2018);
total_AUG2018 = sum(AUG2018, Dep_AUG2018);
total_SEP2018 = sum(SEP2018, Dep_SEP2018);
total_OCT2018 = sum(OCT2018, Dep_OCT2018);
total_NOV2018 = sum(NOV2018, Dep_NOV2018);
total_DEC2018 = sum(DEC2018, Dep_DEC2018);

然后您可以在数据步骤中使用%include来运行它。

data final4;
  set final3;
  by hh_no;
  %include code / source2 ;
run;

答案 2 :(得分:0)

我想提出另一种观点:您在这里遇到的困难是由于使用了宽数据形状和许多列所致。

您可以首先从宽到长转置,而不是使用这种形状的数据,这样,您不必拥有大量total_xxx列,而只需拥有3:total,{{1} }和total_dep,每月排一次。一旦采用这种格式,使用起来就会容易得多,有可能使您避免诉诸宏和墙纸代码。

建议阅读:

Transpose wide to long with dynamic variables

相关问题