Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 对sas变量重新编码并添加前缀_Macros_Sas_Recode - Fatal编程技术网

Macros 对sas变量重新编码并添加前缀

Macros 对sas变量重新编码并添加前缀,macros,sas,recode,Macros,Sas,Recode,假设我有一堆以同样的方式命名的变量,我想对它们重新编码,并为每个变量添加一个前缀,这些变量都是数字 在Stata中,我会做一些类似的事情,比如说变量从eq开始 如何在SAS中执行此操作?我想使用%DO宏,但我不熟悉它们,我想避免使用SQL。如果您能对每个步骤进行解释,我将不胜感激 您可以通过重命名和指示要重命名哪些变量的破折号来完成此操作。注意:以下仅重命名col变量,而不重命名其他变量: 如果使用数字后缀命名变量,那么SAS语法将更容易实现这一点。也就是说,如果有十个变量的名称为eq1,eq2

假设我有一堆以同样的方式命名的变量,我想对它们重新编码,并为每个变量添加一个前缀,这些变量都是数字

在Stata中,我会做一些类似的事情,比如说变量从eq开始

如何在SAS中执行此操作?我想使用%DO宏,但我不熟悉它们,我想避免使用SQL。如果您能对每个步骤进行解释,我将不胜感激

您可以通过重命名和指示要重命名哪些变量的破折号来完成此操作。注意:以下仅重命名col变量,而不重命名其他变量:


如果使用数字后缀命名变量,那么SAS语法将更容易实现这一点。也就是说,如果有十个变量的名称为eq1,eq2,那么您可以使用变量列表来定义这两组变量

有许多方法可以转换重新编码逻辑。如果我们假设你有干净的变量,那么我们可以使用一个布尔表达式来生成一个0/1的结果。因此,如果4和5映射为1,其余映射为0,则可以使用4,5中的x或x>3作为布尔表达式

data want;
  set have;
  array old eq1-eq10 ;
  array new r_eq1-r_eq10 ;
  do i=1 to dim(old);
    new(i) = old(i) in (4,5);
  end;
run;
如果缺少值或存在其他复杂情况,则可能需要使用If/THEN逻辑或SELECT语句,或者可以定义可用于转换值的格式

如果名称列表更为随机,则可能需要使用一些代码生成(如宏代码)来生成新的变量名称

这里有一种在SAS中使用eq:variable list语法的方法,它类似于之前选择的变量语法。对源数据集的空obs=0版本使用PROC TRANSPOSE,以获取具有与您的名称模式匹配的变量名称的数据集

proc transpose data=have(obs=0) out=names;
  var eq: ;
run;
然后使用新旧名称列表生成两个宏变量

proc sql noprint ;
  select _name_
       , cats('r_',_name_)
    into :old_list separated by ' '
       , :new_list separated by ' '
  from names
  ;
quit;
然后可以在数组语句中使用这两个宏变量

  array old &old_list ;
  array new &new_list ;

PROC转置将为变量命名方式提供良好的灵活性

proc transpose data=have(obs=0) out=vars;
   var col1-numeric-col12;
   copy col1;
   run;
proc transpose data=vars out=revars(drop=_:) prefix=RE_;
   id _name_;
   run;
data recode;
   set have;
   if 0 then set revars;
   array c[*] col1-numeric-col12;
   array r[*] re_:;
   call missing(of r[*]);
   do _n_ = 1 to dim(c);
      if      c[_n_] in(1 2 3) then r[_n_] = 0;
      else if c[_n_] in(4 5)   then r[_n_] = 1;
      else                          r[_n_] = c[_n_];
      end;
   run;
proc print;
   run;

编写一个宏来解析几乎完全相同的语法几乎是微不足道的

我不一定要用这个-我更喜欢转置和数组方法,两者都更“时髦”认为“pythonic”,但对于SAS-但这或多或少正是您上面所做的

首先设置数据集:

data class;
  set sashelp.class;
  age_ly = age-1;
  age_ny = age+1;
run;
然后宏:

%macro do_count(data=, out=, prefix=, condition=, recode=, else=, var_start=);
%local dsid varcount varname rc;          *declare local for safety;

%let dsid = %sysfunc(open(&data.,i));       *open the dataset;


%let varcount = %sysfunc(attrn(&dsid,nvars)); *get the count of variables to access;

  data &out.;                                 *now start the main data step;
    set &data.;                               *set the original data set;
    %do i = 1 %to &varcount;                  *iterate over the variables;
      %let varname= %sysfunc(varname(&dsid.,&i.));   *determine the variable name;
      %if %upcase(%substr(&varname.,1,%length(&var_start.))) = %upcase(&var_start.) %then %do;                   *if it matches your pattern then recode it;
        &prefix.&varname. = ifn(&varname. &condition., &recode., &else.);   *this uses IFN - only recodes numerics.  More complicated code would work if this could be character.;
      %end;
    %end;
    %let rc = %sysfunc(close(&dsid));         *clean up after yourself;
  run;

%mend do_count;

   %do_count(data=class, out=class_r, var_start=age, condition= > 14, recode=1, else=0, prefix=p_);
表达式1/4=1意味着值{1,2,3,4}应该重新编码到 一,

也许您根本不需要创建新的变量?如果变量的值为1,2,3,4,5,并且希望将它们视为只有两个组,则可以使用一种格式

proc format ;
  value newgrp 1-4='Group 1' 5='Group 2' ;
run;
首先使用格式定义分组

proc format ;
  value newgrp 1-4='Group 1' 5='Group 2' ;
run;
然后,您可以在分析步骤中使用FORMAT语句,让SAS将五个级别的变量视为只有两个级别

proc freq ;
  tables eq: ;
  format eq: NEWGRP. ;
run;

可以用变量名显示前后数据吗?您正在更改变量名吗?还是制造新的变量?您正在更改变量值吗?如果是,怎么做?例如,1/4=1意味着什么?它看起来像一个明显错误的布尔表达式。我想创建新变量,使用原始变量名,但带有前缀r\ux。表达式1/4=1意味着值{1,2,3,4}应重新编码为1。变量是标量[1,2,3,4,5],我想将4和5重新编码为1,将1,2,3重新编码为0。为什么要重新编码变量?为什么不给变量附加一个格式呢?我不知道这意味着什么,但我想计算它们的平均值,对我来说,生成重新编码的变量通常更简单。这就是我在R、Stata和SPSS中所做的。虽然很有用,但这只是重命名变量。每个数据集的变量数量可能会改变,所以我希望能够使用某种通配符。对不起,您最初所说的重新编码是什么意思还不清楚。查看更新!有什么方法可以简化这个解决方案吗?这是两个步骤,这两个步骤都是你所要求的,所以不,你不能有意义地缩短它;你怎么做?在这种情况下需要它吗?@Tom COL1是在第二次转置中转置的变量。我可能应该使用VAR语句来说明这一点,但默认情况是转置所有的数值变量。有趣的是,我不得不使用ID语句,虽然_NAME_uu是默认的ID变量,但是当使用PREFIX=ID时,它并不是隐含的,所以您不需要它。如果没有它,第一个转置将生成只有1列而不是2列的数据集,第二个转置将生成具有0个观察值而不是1的数据集。看起来也不需要ID语句。至少有9.4版本3。@tom你似乎部分正确。我不需要一个变量来进行转置,但是为了得到我想要的新变量名,我需要ID _NAME;另一方面,它们将被命名为RE_1-RE_6 SYSVLONG4 9.04.01M3P06242015在最后一个代码块中使用了什么&for?这就是引用PROC SQL查询生成的宏变量的方式。&是
宏处理器,用于将以下内容视为宏变量的名称。宏变量的值将被替换为引用,生成的代码将被传递到SAS,就像您在源程序中键入它一样。谢谢,我使用了最后3个代码块来执行我需要的操作,并在数组中添加内容。在SAS中克隆一堆变量并为它们添加前缀需要这么多代码,这似乎很疯狂——这就是我想要做的,所以我的解释可能不清楚?你能解释一下SQL块吗?我不熟悉SAS中的proc。proc SQL只允许您使用SQL代码。INTO子句允许它生成宏变量值。您还可以使用数据步骤将代码行写入文件,并使用%INCLUDE。在SAS中,最有可能的做法是不使用变量,只对它们应用一种格式,以便在分析时动态地进行重新编码。
proc freq ;
  tables eq: ;
  format eq: NEWGRP. ;
run;