Hash 在SAS中重命名哈希合并中的变量

Hash 在SAS中重命名哈希合并中的变量,hash,merge,sas,rename,Hash,Merge,Sas,Rename,我曾试图学习SAS中的哈希联接,但我被困在了多个具有相同变量名的表的情况下(不是键,没关系,而是其他变量) 我想用两个变量Key和Dat连接表A、B和C。名称键和Dat在这三种语言中都是通用的 如果我将所有三个表中的Dat重命名为Dat_A、Dat_B、Dat_C,那么这种语法对我来说是有效的,但这会破坏目的,因为我必须调用所有三个表,这需要时间 此代码适用于: data merged(keep=KEY DAT_A DAT_B DAT_C); if 0 then set A B C;

我曾试图学习SAS中的哈希联接,但我被困在了多个具有相同变量名的表的情况下(不是键,没关系,而是其他变量)

我想用两个变量Key和Dat连接表A、B和C。名称键和Dat在这三种语言中都是通用的

如果我将所有三个表中的Dat重命名为Dat_A、Dat_B、Dat_C,那么这种语法对我来说是有效的,但这会破坏目的,因为我必须调用所有三个表,这需要时间

此代码适用于:

data merged(keep=KEY DAT_A DAT_B DAT_C);
if 0 then
    set A B C;

if _N_ = 1 then
    do;
        declare hash A(dataset:'A');
        A.defineKey('KEY');
        A.defineData('DAT_A');
        A.defineDone();
        declare hash B(dataset:'B');
        B.defineKey('KEY');
        B.defineData('DAT_B');
        B.defineDone();
    end;

set C;

if A.find(key:KEY) = 0 and B.find(key:KEY) = 0 then
    output; run;
SAS网站上提到,您可以在散列声明中指定数据中的选项,因此我认为这可能会起作用

data merged(keep=KEY DAT_A DAT_B DAT_C DAT);
if 0 then
    set A B C;

if _N_ = 1 then
    do;
        declare hash A(dataset:'A (rename=(DAT=DAT_A))');
        A.defineKey('KEY');
        A.defineData('DAT_A');
        A.defineDone();
        declare hash B(dataset:'B (rename=(DAT=DAT_B))');
        B.defineKey('KEY');
        B.defineData('DAT_B');
        B.defineDone();
    end;

set C (rename=(DAT=DAT_C));

if A.find(key:KEY) = 0 and B.find(key:KEY) = 0 then
    output; run;
但是,运行此命令会产生以下错误

错误:变量DAT不在文件WORK.A上

错误:第33行第4列的哈希数据集加载失败

错误:数据步骤组件对象失败。在执行阶段中止

有人有什么想法吗


非常感谢

您将
DAT
包含在输出数据集的
keep=
dataset选项中。但是您的数据步骤不再有变量
DAT
。您已重命名它的所有副本

关于dataset
A
没有
DAT
的错误消息可能是因为您先前尝试将变量重命名为
DAT\U A

下面是使用SASHELP.CLASS的示例

data merged ;
keep NAME AGE_A AGE_B AGE_C ;
if 0 then set
  sashelp.class(rename=(AGE=AGE_A))
  sashelp.class(rename=(AGE=AGE_B))
  sashelp.class(rename=(AGE=AGE_C))
;

if _N_ = 1 then do;
  declare hash A(dataset:'sashelp.class (rename=(AGE=AGE_A) where=(age_a ne 14))');
  A.defineKey('NAME');
  A.defineData('AGE_A');
  A.defineDone();
  declare hash B(dataset:'sashelp.class (rename=(AGE=AGE_B) where=(age_b ne 13))');
  B.defineKey('NAME');
  B.defineData('AGE_B');
  B.defineDone();
end;

set sashelp.class (rename=(AGE=AGE_C));

/* if A.find(key:NAME) = 0 and B.find(key:NAME) = 0 then output; */
if A.find(key:NAME) then call missing(age_a);
if B.find(key:NAME) then call missing(age_b);

run;

在第一个示例中,您已经将DAT重命名为DAT_A、DAT_B和DAT_C。在运行第二个示例之前,您没有重新创建数据集A、B和C吗?检查变量是否已重命名。非常感谢Tom。成功了。如果我可以问一下,在其中使用“If A.find(key:NAME)=0和B.find(key:NAME)=0然后输出”和“If A.find(key:NAME)然后调用missing(age_A);If B.find(key:NAME)然后调用missing(age_B);”有什么区别?您使用的是条件输出语句,仅写入匹配的记录。另一方面,你保留了所有的观察结果。在这种情况下,您需要清除来自不提供任何记录的表的变量。因为变量来自一个数据集,所以它们被保留下来,需要显式地重置为missing。有点像内部连接还是外部连接?有点像。更像是SAS datastep合并,使用和不使用IN=dataset选项来检查两个数据集是否都有贡献。对于一对一的比赛,他们是一样的。