【问题标题】:Send subset of data to SAS DS2 thread将数据子集发送到 SAS DS2 线程
【发布时间】:2015-02-03 19:10:48
【问题描述】:

我有一个包含 5 个组的数据集,我想使用 SAS 中的 DS2 过程同时计算组均值。

模拟数据集:

data sim;
    call streaminit(7);
    do group = 1 to 5;
        do pt = 1 to 500;
            x = rand('ERLANG', group);
            output;
        end;
    end;
run;

我设想它的工作方式是 5 个线程中的每一个都接收与特定组相对应的数据子集。 x 的平均值是在每个子集上计算的,如下所示:

proc ds2;
    thread t / overwrite=yes;
        dcl double n sum mean;

        method init();
            n = 0;
            sum = 0;
            mean = .;
        end;

        method run();
            set sim;    /* Or perhaps a subsetted dataset */
            sum + x;
            n + 1;
        end;

        method term();
            mean = sum / n;
            output;
        end;
    endthread;

    ...
quit;

问题是,如果您调用一个线程来处理如下所示的数据集,则行将被发送到 5 个线程,所有这些线程都是无条件的(即不考虑组)。

    data test / overwrite=yes;
        dcl thread t t_instance;
        method run();
            set from t_instance threads=5;
        end;
    enddata;

我如何告诉 SAS 通过group 对数据进行子集化并将每个子集传递给它自己的线程?

【问题讨论】:

  • the documentation 看来您需要一个 by 语句来指定分组。进一步讨论here。但是,从我的肤浅阅读来看,这是否仅与数据库处理有关。
  • @SRSwift:我熟悉 BY 组处理,并且针对这种情况进行了研究。我假设我需要在某处使用by 语句,但我无法弄清楚如何使用它为每个组生成一个线程。
  • 我无权访问 DS2,但我假设它遵循基本 SAS 中的 set 语句。见here
  • @SRSwift:我知道一般如何使用by 语句。它确实低于set,就像在数据步骤中一样。我的问题是利用组来完成特定任务。我搜索了 SAS DS2 文档,但没有找到与我的需求直接相关的内容,这就是我发布到 SO 的原因。
  • sas-ds2 标签已创建 - 请随时改进 wiki。

标签: multithreading parallel-processing sas sas-ds2


【解决方案1】:

我相信你必须在run()方法中添加by语句,然后添加一些代码来处理by group(即,如果你希望它为last.group输出然后添加代码来做所以并清除总数)。 DS2 应该是智能的并且每个by 组使用一个线程(或者,至少,每个线程处理整个by 组)。我不确定如果您从磁盘读取是否会看到很大的改进(因为线程优势可能小于磁盘读取时间),但谁知道呢。

下面的唯一更改是在run() 中,并添加proc means 以检查我自己。

data sim;
    call streaminit(7);
    do group = 1 to 5;
        do pt = 1 to 500;
            x = rand('ERLANG', group);
            output;
        end;
    end;
run;

proc ds2;
    thread t / overwrite=yes;
        dcl double n sum mean ;

        method init();
            n = 0;
            sum = 0;
            mean = .;
        end;

        method run();
            set sim;
            by group;
            sum + x;
            n + 1;
            if last.group then do;
                mean = sum / n;
                output;
                n=0;
                sum=0;
            end;
        end;

        method term();
        end;
    endthread;
  run;

  data test / overwrite=yes;
        dcl thread t t_instance;
        method run();
            set from t_instance threads=5; 
        end;
    enddata;
    run;    
quit;

proc means data=sim;
class group;
var x;
run;

【讨论】:

  • @Alex 我根本没有改变你的电话——它仍然在上面的代码中(向下滚动)。出于组织目的,我只是将它移到了 PROC DS2 块内。
  • 呃,对。向下滚动很有用。对此感到抱歉。
  • 如果你执行这个并查看 DS2 的计算平均值,它们都是 1。
  • 嗯,对我来说不是这样——他们完美地匹配了 PROC MEANS 的意思。让我看看是不是我改错了什么。
  • @Alex 我不明白。我得到了 1.003105、1.998972、2.946343、3.94346119 和 5.13233902 的平均值,它们与 PROC MEANS 输出完美匹配。 (注意,我在您的第一个数据步骤中将随机种子设置为 7,因此您应该能够以相同的方式复制结果)。这是 9.4TS1M2;如果您有更早的 9.4,这可能在该版本中无法正常工作?
猜你喜欢
  • 2017-09-27
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
相关资源
最近更新 更多