Macros SAS-查找目录中所有数据集的回文 任务:

Macros SAS-查找目录中所有数据集的回文 任务:,macros,sas,palindrome,Macros,Sas,Palindrome,我需要识别目录中的所有回文。我使用proc contents和proc sort来标识目录中的数据集,如下所示: proc contents data = dPath._all_ out = dFiles (keep = memname); run; proc sort data = dFiles nodupkey; by memname;run; 我想识别这个目录中的回文 问题: 我计划使用宏,因为我需要对目录中的所有数据集执行此操作。因此,与用户输入字符串检查是否有回文不同,我需要动

我需要识别目录中的所有回文。我使用proc contents和proc sort来标识目录中的数据集,如下所示:

proc contents data = dPath._all_ out = dFiles (keep = memname);
run; 

proc sort data = dFiles nodupkey; by memname;run; 
我想识别这个目录中的回文

问题: 我计划使用宏,因为我需要对目录中的所有数据集执行此操作。因此,与用户输入字符串检查是否有回文不同,我需要动态地进行检查,即识别数据集中的任何回文

更新: 正如您在上面的图片中所看到的,我能够成功地为区分大小写和不区分大小写的情况标记回文。我想将回文的特定元素输出到一个单独的数据集。目前,我只能输出包含回文的整行

代码: 如果memtype=“DATA”,则代码中的Memname将仅包含表名。 使用上面的代码检查表名中的回文;尝试:

%macro palindrome (parameter = ); 
%let string = %sysfunc(reverse(%sysfunc(compress("&parameter ",,sp);
%let reverse = %sysfunc(compress(["&parameter ");
%if %upcase(&string.) = %upcase(&reverse.)  %then %do;
ods output = "/palindrome"
%end;

data work.palindromes;
set work.dfiles;
%macro palindrome (parameter = Memname);
run;

不知道为什么您的图像显示了变量名的反转

可以使用数据步函数
VNAME()
检索与数组引用对应的基础变量名。此外,可以使用数据步长函数
VVALUE
获得变量的格式化值。这两个函数都有一个动态版本--
VNAMEX
VVALUEX
。基于阵列的解决方案不需要使用函数的
X
版本

通过数组处理所有变量有点棘手,因为您需要额外的变量来执行处理,并且您不希望测试这些变量的回文性。在本例中,工作者变量名使用以
\u pal
开头的约定,希望避免变量名与正在处理的数据集发生冲突。该示例处理单个数据集,但如何对代码进行宏化并使其对传递的数据集名称起作用应该是显而易见的

data want(keep=_palds_ _palrow_ _palvar_ _palval_);
  set sashelp.class;

  array _pals_ _character_;  * array elements are those character variables in the pdv at this point in the data step;
  array _palx_ _numeric_;    * array elements are those numeric variables in the pdv at this point in the data step;

  attrib
    _palds_ length  = $42
    _palrow_ length = 8
    _palvar_ length = $32
    _palval_ length = $500
  ;

  * check raw character value;
  do _palindex_ = 1 to dim(_pals_);
    if length (_pals_(_palindex_)) > lengthm(_palval_) then do;
      _palvar_ = vname (_pals_(_palindex_));
      put "NOTE: sashelp.class " _n_= _palVar_ " had a value that is longer than _palval_ container";
      continue;
    end;

    if _pals_(_palindex_) = reverse(trim(_pals_(_palindex_))) then do;
      _palds_ = "sashelp.class";
      _palrow_ = _n_;
      _palvar_ = vname (_pals_(_palindex_));
      _palval_ = _pals_(_palindex_);
    end;
  end;

  * check formatted numeric value;
  do _palindex_ = 1 to dim(_palx_);
    if left(vvalue(_palx_(_palindex_))) = reverse(trim(vvalue(_palx_(_palindex_)))) then do;
      _palds_ = "sashelp.class";
      _palrow_ = _n_;
      _palvar_ = vname (_palx_(_palindex_));
      _palval_ = _palx_(_palindex_);
    end;
  end;
run;
要显式避免名称冲突的宏必须对要处理的数据集执行一些简单的检查,以便生成不冲突的辅助变量名称

如果libref连接到远程主机,那么处理libref的所有成员可能会占用大量资源,因此健壮的解决方案可能需要跳过这些

其他一些方法:

  • 使用
    callvnext
    例程迭代pdv变量
  • 在不依赖数组的数据步骤中,使用字典表或proc内容输出作为生成变量测试墙的基础

您将不会使用宏来计算值。了解如何编写数据步骤以确定回文值是否出现在单个列中。您可以从那里展开,并对所有字符变量数组中的每个元素执行相同的检查
数组字符串变量\u character\u
然后决定是否还要检查回文数字值,如果是,则对
数组num\u variables\u numeric\u中的每个元素应用数字测试处理单个数据集后,请对该过程进行宏化,并在数据集名称中传递一个宏参数。然后,您可以为库中每个不同的数据集名称调用宏,这些名称是从DICTIONARY.TABLES获得的
Proc Contents
SASHELP.VTABLE
或Proc SQL
,其中libname=“your libref”
@datanalyst请使用您尝试过的代码和遇到的任何问题更新您的问题。提示:将trim()嵌套在reverse()中,以防止尾随空格变为前导空格<代码>回文标志=(项目eq反向(修剪(项目))@Richard谢谢你的评论。我已经用下一步要实现的步骤更新了代码。我能够识别回文,现在我希望将数组回文中的特定元素输出到一个单独的数据集,该数据集可以识别它是区分大小写还是不区分大小写的回文。再次感谢您的指导。
data want(keep=_palds_ _palrow_ _palvar_ _palval_);
  set sashelp.class;

  array _pals_ _character_;  * array elements are those character variables in the pdv at this point in the data step;
  array _palx_ _numeric_;    * array elements are those numeric variables in the pdv at this point in the data step;

  attrib
    _palds_ length  = $42
    _palrow_ length = 8
    _palvar_ length = $32
    _palval_ length = $500
  ;

  * check raw character value;
  do _palindex_ = 1 to dim(_pals_);
    if length (_pals_(_palindex_)) > lengthm(_palval_) then do;
      _palvar_ = vname (_pals_(_palindex_));
      put "NOTE: sashelp.class " _n_= _palVar_ " had a value that is longer than _palval_ container";
      continue;
    end;

    if _pals_(_palindex_) = reverse(trim(_pals_(_palindex_))) then do;
      _palds_ = "sashelp.class";
      _palrow_ = _n_;
      _palvar_ = vname (_pals_(_palindex_));
      _palval_ = _pals_(_palindex_);
    end;
  end;

  * check formatted numeric value;
  do _palindex_ = 1 to dim(_palx_);
    if left(vvalue(_palx_(_palindex_))) = reverse(trim(vvalue(_palx_(_palindex_)))) then do;
      _palds_ = "sashelp.class";
      _palrow_ = _n_;
      _palvar_ = vname (_palx_(_palindex_));
      _palval_ = _palx_(_palindex_);
    end;
  end;
run;