【问题标题】:Sort by minimum value of each group in ascending order of value in SAS在SAS中按值升序按每组的最小值排序
【发布时间】:2019-10-20 02:56:11
【问题描述】:

我正在尝试按每个组的最小值对值进行升序排序。我尝试了几种使用分组和排序的不同组合,但无法正确按组排序。什么是最有效的方法?

我试过这个:

PROC SQL;
CREATE TABLE NEED AS 
SELECT DISTINCT *
FROM HAVE
GROUP BY ID,VALUE
ORDER BY VALUE;
QUIT; 

使用此输出并认为它会根据 ID 分组进行排序

【问题讨论】:

  • 您尝试了什么?尝试有什么问题?请发布代码和minimal reproducible example
  • 好的,我发布了代码和示例。
  • 您想按 ID 的最小值 VALUE 对 ID 进行排序吗?如果是这样,那么您需要在该 ID 的每个观察值上都有该最小值。

标签: sorting sas grouping proc-sql


【解决方案1】:

默认情况下,SQL Procedure 实现汇总统计的自动重新合并。

Per Documentation

重新合并数据

当您在 SELECT 子句或 HAVING 子句中使用汇总函数时,您可能会在 SAS 日志中看到以下消息:
NOTE: The query requires remerging summary statistics back with the original data.

重新合并的过程涉及两次数据传递。

第一遍,PROC SQL
• 计算并返回汇总函数的值。然后它使用结果来计算汇总函数参与的算术表达式。
• 根据 GROUP BY 子句对数据进行分组。

在第二遍中,PROC SQL 检索它需要在输出中显示的任何其他列和行。

注意:要指定 PROC SQL 不处理使用数据重新合并的查询,请使用 PROC SQL NOREMERGE 选项或 NOSQLREMERGE 系统选项。如果在设置 NOMERGE 选项或 NOSQLREMERGE 系统选项时尝试重新合并,则会将错误写入 SAS 日志。

依赖自动重新合并的查询类似于以下示例:

proc sql;
  create table want as 
  select all.* from
  (select make, min(msrp) as lowest from sashelp.cars group by make) as sequencer
  join 
  sashelp.cars as all on sequencer.make = all.make
  order by sequencer.lowest, all.make, all.msrp
  ;

LOG 窗口将根据lowest 的使用方式显示NOTE

NOTE: The query as specified involves ordering by an item that doesn't appear in its SELECT clause.

【讨论】:

    【解决方案2】:

    如果你想按最小值排序,那么它需要在每个观察值上。

    PROC SQL;
    CREATE TABLE NEED AS 
      SELECT DISTINCT *,min(value) as min_value
      FROM HAVE
      GROUP BY ID
      order by min_value,id,value
    ;
    QUIT; 
    

    【讨论】:

    • 虽然这可能是允许的 SAS 查询,但它违反了 SQL 标准的规则,因为 *GROUP BY 一起使用。此查询应在 SAS 之外失败。 SAS 可能会发出警告。也许未来的 SAS 版本将支持内联聚合的窗口函数:MIN(value) OVER (PARTITION BY ID)。另外,你不应该在ORDER BY 中使用calculated 吗?
    • 当然,在其他 SQL 实现中,您可能仅限于通过子查询生成最小值并重新合并它,但是获取可用于排序的实际变量的概念很重要。
    • 是的,谢谢你的这个结果,因为它比我正在研究的另一个更优雅:PROC SORT DATA=HAVE;按 ID 值;跑;数据需求;设置有;计数 + 1;按 ID ; IF FIRST.ID THEN COUNT=1;跑;程序 SQL; CREATE TABLE NEED2 AS SELECT DISTINCT * FROM NEED GROUP BY ID, VALUE, COUNT ORDER BY MIN_VALUE,ID;退出;
    【解决方案3】:

    你可以尝试一个简单的排序:

    proc sort data = have out = want;
      by descending ID value;
    run;
    

    【讨论】:

    • 感谢您的帖子,但这并不是根据每个 ID 组的最小值进行排序的。
    猜你喜欢
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 2015-06-18
    • 2014-10-29
    • 1970-01-01
    相关资源
    最近更新 更多