修改by变量中的多个观察值

时间:2015-05-28 04:04:18

标签: sas

data a1

col1 col2 flag
a    2    .
b    3    .
a    4    .
c    1    .

对于数据a1flag始终缺失。我想使用a2更新多行。

data a2

col1 flag
a    1

理想输出:

col1 col2 flag
a    2    1
b    3    .
a    4    1
c    1    .

但这不会更新by声明中的所有记录。

data a1;
modify a1 a2;
by col1;
run;

编辑问题

实际上a1是服务器上非常大的数据集。因此,我更喜欢修改它(如果可能的话),而不是创建一个新的。否则,我必须首先删除先前的a1并将新的a1从本地复制到服务器,这将花费更多的时间。

4 个答案:

答案 0 :(得分:1)

如果你想用MODIFY做这个,你必须以某种方式遍历修改数据集,否则它只会替换第一行(因为其他数据集将用完记录 - 通常这就像合并一样,其中一旦找到匹配,它就会前进到下一个记录)。这是一个选项 - 还有其他选择。

data a1(index=(col1));
  input col1 $ col2 flag;
datalines;
a    2    .
b    3    .
a    4    .
c    1    .
;;;;
run;

data a2(index=(col1));
  col1='a'; 
  flag=1;
run;

data a1;
    set a2(rename=flag=flag2);
    do _n_ = 1 to nobs_a1;
      modify a1 key=col1 nobs=nobs_a1;
      if _iorc_=0 then do;
        flag=flag2;
        replace;
      end;
    end;
    if _iorc_=%sysrc(_DSENOM) then _error_=0;
run;

答案 1 :(得分:0)

如果您没有使用Merge语句进行排序问题,则只需更改合并方法即可。 如果A1中的标志总是丢失,您可以删除它,否则您应该临时重命名它,以免丢失这些信息。 这里我将使用哈希对象合并A1和A2,这种方法不需要对数据集进行任何先前的排序。

data final_merged(drop = finder);
length flag 8.; /*please change length with the real one, use $ if char*/
if _N_ = 1 then do;
            declare hash merger(dataset:'A2');
            merger.definekey('col1');
            merger.DefineData ('flag');
            merger.definedone();
end;
set A1(drop=flag);
finder = merger.find();
if finder ne 0 then flag = .; 
/*then flag='' or then flag='unknown' as you want if flag is a character var*/
run;

请告诉我这是否有帮助。

答案 2 :(得分:0)

您可以执行以下操作,但SQL会对观察结果进行排序,因此不确定这对您有多大用处? (您可以随时使用ordvar=_n_;进行预处理,然后在其上对SQL语句进行排序(如果有帮助):

数据:

data a1 ;
input col1 $ col2 flag ;
cards ;
a 2 .
b 3 .
a 4 .
c 1 .
;run ;

data a2 ;
input col1 $ flag ;
cards ;
a 1 
;run ;

合并:

proc sql ;
create table output as
  select a.col1, a.col2, b.flag
  from a1 a
  left join
  a2 b
  on a.col1=b.col1
;quit ;

答案 3 :(得分:0)

要尝试一次性完成,如何创建包含a2映射的两个宏变量?

proc sql ;
select distinct col1, flag
into :colvals separated by '', :flagvals separated by ''
from a2
;quit ;

将标志设置为两个宏变量之间的相应字符位置:

data a1 ;
  set a1 ;
  if findc("&colvals",col1) then 
    flag=input(substr("&flagvals", findc("&colvals",col1),1),8.) ;
run ;