首页 > 解决方案 > 如何做双循环以在 SAS 中生成保留列表?

问题描述

我有一个非常大的数据集,包含 1000 多列,列名的格式如下:

WORLDDATA.table2_usa_2017_population
WORLDDATA.table2_japan_2017_gnp

我只需要为少数几个国家保留这些参数的一个子集。我指定自定义列表:

%let list1 = usa canada uk japan southafrica;
%let list2 = population crimerate gnp;

如何像这样执行双重 for 循环:

param_list = []
for (i in list1) {
  for (j in list2) {
     param_name = WORLDDATA.table2_{list1[i]}_2017_{list2[j]}
     param_list.append(param_name)
  }
}

这样我就可以使用 param_list

data final_dataset;
  set WORLDDATA.table2;
  keep {param_list};
run;

谢谢!

标签: for-loopsas

解决方案


您的原始数据集包含数据项 countrytopic编码到列名(元数据)中,您可能需要转置数据以用于 SAS 过程步骤,这些步骤将使用和where等语句。byclass

Proc TRANSPOSE可以将数据从宽转高,并且输出将有一个名为的列_NAME_,可以在where=(where-statement)输出数据集的选项中使用。where语句将是一个正则表达式,将您的列表指定为|组中的交替 ( ) 项(例如(item-1|...|item-N))。正则表达式引擎将执行问题伪代码中的嵌套循环所执行的隐式外连接。正则表达式模式将使用 /ix 修饰符,以便为人类可读性而格式化的模式也忽略大​​小写。

为了对Proc TRANSPOSE数据集的每一行进行透视,数据集需要具有逐行不同的行键(一个或多个变量组合)。

未经测试的例子:

proc transpose data=have_wide out=want_subset_categorical (where=(
  prxmatch("(?ix)/
    table2_
      %sysfunc(translate(&LIST1.,|,%str( ))   (?# list 1 spaces converted to | ors )
    _2017_
      %sysfunc(translate(&LIST2.,|,%str( ))   (?# list 2 spaces converted to | ors )

  /",_name_)
));
  by <row-key>;
run;

推荐阅读