【问题标题】:SAS equivalent to R’s is.element()SAS 等价于 R 的 is.element()
【发布时间】:2016-11-14 16:25:01
【问题描述】:

今天第一次打开sas,正在看同事写的一些代码。

假设我有一些数据 (import) 出现重复,但我只想要那些具有唯一编号的数据,名为 VTNR。

首先她寻找唯一的数字:

    data M.import;
    set M.import;

    by VTNR;
    if first.VTNR=1 then unique=1;
    run;

然后她用重复的数字创建一个表格:

    data M.import_dup1;
    set M.import;

    where unique^=1;
    run;

最后是一个包含所有重复项的表。 但在这里她真的是对数字进行硬编码,例如:

    data M.import_dup2;
    set M.import;
    where VTNR in (130001292951,130100975613,130107546425,130108026864,130131307133,130134696722,130136267001,130137413257,130137839451,130138291041);
    run;

我相信一定有更好的方法。

由于我只熟悉 R,所以我会写如下内容:

import_dup2 <- subset(import, is.element(import$VTNR, import_dup1$VTNR))

我想 sas 也必须有类似 $ 的东西?

【问题讨论】:

  • 使用 uniqueout 和 Dupout 选项查看 proc 排序。
  • 如果您需要 SAS 程序员的帮助,那么您需要解释您的 R 代码是做什么的。此外,您应该解释您尝试使用 R 代码解决的问题,而不仅仅是它是如何工作的。一般来说,在使用不同语言时,您需要调整自己的方法来解决问题。

标签: sas duplicates unique subset


【解决方案1】:

在我看来,它是最直接的 R 代码翻译

import_dup2 <- subset(import, is.element(import$VTNR, import_dup1$VTNR))

将使用 SQL 代码

proc sql;
 create table import_dup2 as 
   select * from import
   where VTNR in (select VTNR from import_dup1)
 ;
quit;

但是,如果您的目的是在 IMPORT 中找到每个 VTNR 值具有多个观察值的观察值,则无需先创建其他表。

data import_dup2 ;
  set import;
  by VTNR ;
  if not (first.VTNR and last.VTNR);
run;

【讨论】:

  • 请注意,要使用by,数据集必须按该变量排序。
【解决方案2】:

我会使用 PROC SORT 中的选项。 确保指定 OUT= 数据集,否则您将覆盖原始数据。

/*Generate fake data with dups*/
data class;
set sashelp.class sashelp.class(obs=5);
run;

/*Create unique and dup dataset*/
proc sort data=class nouniquekey uniqueout=uniquerecs out=dups;
by name;
run;

/*Display results - for demo*/
proc print data=uniquerecs;
title 'Unique Records';
run;

proc print data=dups;
title 'Duplicate Records';
run;

【讨论】:

    【解决方案3】:

    上述解决方案可以为您提供重复但不是唯一值。在 SAS 中有很多可能的方法来实现这两者。 SQL 解决方案非常容易理解。

    proc sql;
    create table no_duplicates as
        select *
            from import
            group by VTNR
            having count(*) = 1
        ;
    create table all_duplicates as
        select *
            from import
            group by VTNR
            having count(*) > 1
        ;
    quit;
    

    【讨论】:

    • 我能理解你的方法,但我真的在寻找类似is.element()-way(和$)的东西,因为我发现它对各种子集非常有用。还是sas中不存在这个?
    • SAS Base 不是矩阵语言。如果您可以访问 SAS/IML,则可以进行矢量比较。但在 IML 中,您也可以只使用 R 代码。
    【解决方案4】:

    我会使用 Reeza 或 Tom 的解决方案,但为了完整起见,类似于 R 的解决方案(以及您预先存在的代码)将是三个步骤。再说一次,我不会在这里使用它,因为它是你可以更轻松地完成的工作,但这个概念在其他情况下很有帮助。

    首先,获取重复数据集 - 她的方法或 proc sort

    proc sort nodupkey data=have out=nodups dupout=dups;
      by byvar;
    run;
    

    然后将它们拉入宏列表:

    proc sql;
      select byvar 
        into :duplist separated by ','
        from dups;
    quit;
    

    然后你将它们放在&amp;duplist. 中并可以像这样使用它们:

    data want;
      set have;
      if not (byvar in &duplist.);
    run;
    

    【讨论】:

      【解决方案5】:
      data want;
         set import;
         where VTNR in import_dup1;
      run;
      

      【讨论】:

      • 这看起来正是我想要实现的,但是当我输入以下代码时,会产生零行。 data M.want; set M.import; where VTNR in M.import_dup1; run;(我也试过不使用M.,结果相同。)
      • 如果您能提供一个小的示例数据将非常有帮助。
      • 我正在加载一个无法在此处上传的 csv.File。但 VTNR 是最好的 32。如果这有什么不同。所以“失踪”M. 没有引起问题?
      • 那不是有效的代码。 IN 运算符需要一个值列表。它不能使用变量名。而且它绝对不能使用数据集名称。
      • 虽然此代码可能有助于解决问题,但提供有关它为什么和/或如何回答问题的额外上下文将显着提高其长期价值。请编辑您的答案以添加一些解释。
      猜你喜欢
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多