【问题标题】:Declared vector as parameter of a SAS function将向量声明为 SAS 函数的参数
【发布时间】:2025-11-22 14:25:01
【问题描述】:

我目前正在学习 SAS,已经了解 R 和其他编程语言,我对如何声明向量感到困惑。

我创建了一个模仿 R cut 函数的小函数:

proc fcmp outlib=sasuser.funcs.trial;
function cut(var, cutoff1, cutoff2, cutoff3, value1, value2, value3, value4);
    if  var<cutoff1 then x=value1;
    if  var>=cutoff1 & var<cutoff2 then x=value2;
    if  var>=cutoff2 & var<cutoff3 then x=value3;
    if  var>=cutoff3 then x=value4;
    return (x);
endsub;
CUTTED_COL = cut(NOT_CUTTED_COL, 3.5, 5, 7.5, 0, 0.5, 1, 2);

该函数运行良好,但与此数量的参数相关。这里,var 是数据集中的一列,我将用它来创建另一个列。

为了进行下一步,我想添加参数,因为在 R 中名为 vectors。我认为 vectors 在 SAS 中被命名为 arrays,但我不确定它是否是相同的结构没错。

proc fcmp outlib=sasuser.funcs.trial;
function cut2(var, cutoffs, values);
    /*loop over vectors with a do*/;
    return (x);
endsub;
CUTTED_COL = cut(NOT_CUTTED_COL, {3.5, 5, 7.5}, {0, 0.5, 1, 2});

当然,这种语法失败得很惨。怎么写正确?

注意:即使有比自定义函数更好的方法(我尝试了 proc 格式,但它不是我想要的),关于向量和函数的真正问题的答案也非常欢迎教育目的。
NB2:如果答案是 RTFM,我想知道是哪一部分

最后:这是我使用 DomPazz 的代码 (link) 编写的 cut 函数。像魅力一样工作。

【问题讨论】:

    标签: vector sas cut


    【解决方案1】:

    DomPazz 已经发布了如何将数组传递给 FCMP 函数的答案。但是您的问题看起来应该只用一种格式来解决。如果你定义这样的格式。

    proc format ;
      value cut 
       low -< 3.5 = '0'
       3.5 -< 5 = '0.5'
       5 -< 7.5 = '1'
       7.5 - high = '2'
      ;
    run;
    

    然后您可以使用它来创建新变量。

    cut2 = input(put(not_cut,cut.),32.);
    

    这是一个基于格式的解决方案和基于公式的解决方案的工作示例。

    data want ;
      array cutoff (3) _temporary_ (3.5 5 7.5);
      array outcome (4) _temporary_ (0 0.5 1 2);
      input not_cut @@ ;
      do i=1 to dim(cutoff) until (not_cut < cutoff(i));
      end;
      cut=outcome(i);
      cut2 = input(put(not_cut,cut.),32.);
    cards;
    1 3.5 4 5 6 7.5 8
    ;
    

    输出;

    Obs    not_cut    i    cut    cut2
    
     1       1.0      1    0.0     0.0
     2       3.5      2    0.5     0.5
     3       4.0      2    0.5     0.5
     4       5.0      3    1.0     1.0
     5       6.0      3    1.0     1.0
     6       7.5      4    2.0     2.0
     7       8.0      4    2.0     2.0
    

    【讨论】:

      【解决方案2】:

      您可以将参数声明为数组(向量)。试试这个:

      options cmplib=work.fns;
      
      proc fcmp outlib=work.fns.test;
      function cut2(var, cutoffs[*], values[*]);
         put var=;
         put cutoffs=;
         put values=;
         return (1);
      endsub;
      run;
      
      data _null_;
         array cutoffs[3] (1 2 3);
         array values[3] (4 5 6);
      
          x = cut2(1,cutoffs,values);
      run;
      

      这会将以下内容放入 SAS 日志中:

      96   data _null_;
      97   array cutoffs[3] (1 2 3);
      98   array values[3] (4 5 6);
      99
      100  x = cut2(1,cutoffs,values);
      101  run;
      
      var=1
      cutoffs[1]=1 cutoffs[2]=2 cutoffs[3]=3
      values[1]=4 values[2]=5 values[3]=6
      

      【讨论】:

      • 谢谢,这看起来很棒!但这不会在 Log 窗口中输出任何内容,是否正常?我假设那些 put 语句应该记录变量,不是吗?
      • 有没有办法在函数的参数中直接声明数组?
      • 不幸的是,没有。 SAS 要求您在传递数组之前声明该数组。
      最近更新 更多