SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 1787|回复: 11
打印 上一主题 下一主题

求助:怎么将两个表对应的元素求乘积?

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2009-8-27 08:48:18 | 只看该作者

求助:怎么将两个表对应的元素求乘积?

有以下两个表,表m中所有变量都可以在表n中找到(但表n中有些变量表m没有),表m的所有id也能在表n中找到(但表n中有些id表m没有),现在要更新表m,使其每个变量指定ID的观测值乘以表n的对应值(变量名和ID号相同)。

需要说明的是变量有很多(>1000),观测值也有很多(>100000)

谢谢高人 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->  <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->

data m;
   input ID $ s01 s02 s04;
cards;
001 100 10 10
002 20 50 .
003 30 10 10
004 40 . 10
007 . 10 .
008 100 20 40
;

data n;
   input ID $ s01 s02 s03 s04;
cards;
001 80 30 30 10
002 20 50 10 15
003 30 10 10 20
004 40 . 10 .
005 20 20 10 90
006 . 10 . 20
007 100 20 40 10
008 90 20 20 30
;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2009-8-27 09:00:41 | 只看该作者

Re: 求助:怎么将两个表对应的元素求乘积?

盼望高手回复 <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->  <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->  <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2009-8-27 11:10:37 | 只看该作者

Re: 求助:怎么将两个表对应的元素求乘积?

data m;
input ID $ s01 s02 s04;
cards;
001 100 10 10
002 20 50 .
003 30 10 10
004 40 . 10
007 . 10 .
008 100 20 40
;

data n;
input ID $ s01 s02 s03 s04;
cards;
001 80 30 30 10
002 20 50 10 15
003 30 10 10 20
004 40 . 10 .
005 20 20 10 90
006 . 10 . 20
007 100 20 40 10
008 90 20 20 30
;
run;

[code:2dn27qvd]/*you can either manually or automatically get the two macro variables by pre-treatment code */
%let dim=3;
%let keepvars=ID  s01 s02 s04;

data mm(keep=&amp;keepvars);
    set m;
    masterid=id;
    array numarr _numeric_;
    array temparr (1&#58;&amp;dim) _temporary_;
    do  i=1 to dim(numarr);
        temparr(i)=numarr(i);
    end;
    do until (gotone);
        point+1;
        set n point=point;
        if  masterid=id then
        do;
        gotone=1;
        do  i=1 to dim(numarr);
            numarr(i)=numarr(i)*temparr(i);
        end;
        end;
    end;
run;[/code:2dn27qvd]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2009-8-27 13:19:34 | 只看该作者

Re: 求助:怎么将两个表对应的元素求乘积?

改了hopewell的一段代码
先取出列名称到宏变量,然后循环生成sql语句。

%macro multi_ds(dsname,dsname2,rltname);
   options nosymbolgen nomprint;
   %let dsid=%sysfunc(open(&amp;dsname,i));
   %let varnum=%sysfunc(attrn(&amp;dsid,nvars));
   %let varlist=;
   %do i=1 %to &amp;varnum;
      %let varlist=&amp;varlist %sysfunc(varname(&amp;dsid,&amp;i));
   %end;
   %let rc=%sysfunc(close(&amp;dsid));
   proc sql noprint;
     create table &amp;rltname as
     select m.id
         %do i=1 %to &amp;varnum;
           %let fldname=%scan(&amp;varlist,&amp;i);
           %if %upcase(&amp;fldname) ne ID %then %do;
             ,m.&amp;fldname * n.&amp;fldname as &amp;fldname
           %end;
     %end;
     from &amp;dsname as m inner join &amp;dsname2 as n
     on m.id=n.id
     ;
   quit;
%mend;
%multi_ds(work.m,work.n,test1);
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2009-8-27 13:23:16 | 只看该作者

Re: 求助:怎么将两个表对应的元素求乘积?

ahuige大师,额理解的对不?
[code:17f48kvb]%let dim=3;                                     /* 除ID外,s变量的个数 */
%let keepvars=ID  s01 s02 s04;             /* m数据集的变量列表 */

data mm(keep=&amp;keepvars);                   /* keep变量 */
    set m;                                 /* 读取数据集m */
    masterid=id;                           /* 相当于给id重命名,以便判断条件m&#46;id=n&#46;id */
    array numarr _numeric_;                     /* 为s系列变量创建数组(id是character) */
    array temparr (1&#58;&amp;dim) _temporary_;         /* 创建临时数组,&amp;dim是s变量的个数 */
    do  i=1 to dim(numarr);                     /* 用s系列变量的值给临时数组赋初值 */
        temparr(i)=numarr(i);
    end;
    do until (gotone);                    /* do until循环 */
        point+1;                          /* 观测号加1 */
        set n point=point;                /* 用观测号直接读取数据集n(set的point选项) */
        if  masterid=id then
        do;                                      /* 判断条件m&#46;id=n&#46;id */
        gotone=1;                           /* 退出do until循环 */
        do  i=1 to dim(numarr);                  /* 数组计算乘积 */
            numarr(i)=numarr(i)*temparr(i);
        end;
        end;
    end;
run;[/code:17f48kvb]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2009-8-27 13:48:17 | 只看该作者

Re: 求助:怎么将两个表对应的元素求乘积?

TO: keynes
这里真的没我什么事,那段代码也是我从PAPER中抄来的,我就是跟人屁股后头学点东西,能抄对就不错了,没自己的东西
我每次取变量清单都习惯性的用proc contents,看了你的程序才想起来varname()不就能取变量名吗,笨死算了
请教个问题,在MACRO中,宏变量length最大是65534,要是数据集M的变量很多,名字又很长的话,理论上就要小心宏变量varlist的长度是否超过的问题了吧.
[code:uczeqqa4]%do i=1 %to &amp;varnum;
     %let varlist=&amp;varlist %sysfunc(varname(&amp;dsid,&amp;i));
%end; [/code:uczeqqa4]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2009-8-27 21:08:12 | 只看该作者

Re: 求助:怎么将两个表对应的元素求乘积?

谢谢各位大师~~

如果把问题再弄复杂点,表m中也有些变量表n没有,这时候需要先把表m中的这些变量删除掉,然后再来相乘,怎么改呢?

虽然我会自己写几行先把表n先处理一下,但是怎么都不能在前面两位大侠的基础上改 <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->  <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2009-8-28 08:52:10 | 只看该作者

Re: 求助:怎么将两个表对应的元素求乘积?

举一要会反三
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2009-8-31 16:05:24 | 只看该作者

Re: 求助:怎么将两个表对应的元素求乘积?

大家好,
    我想问一下,为什么楼主的问题不用sql来解决呢,多简单啊,还是我理解的有误?
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2009-8-31 16:53:16 | 只看该作者

Re: 求助:怎么将两个表对应的元素求乘积?

TO : amanda
keynes就是使用SQL实现的呀,你要有好方法也贡献出来吧.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2026-2-6 00:36 , Processed in 0.103243 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表