楼主: lchw001
1179 8

[有偿编程] 编码求助 [推广有奖]

  • 0关注
  • 0粉丝

大专生

53%

还不是VIP/贵宾

-

威望
0
论坛币
742 个
通用积分
212.8637
学术水平
12 点
热心指数
13 点
信用等级
12 点
经验
1082 点
帖子
50
精华
0
在线时间
49 小时
注册时间
2011-8-8
最后登录
2024-3-9

50论坛币
我的数据如下:
id    rs1    rs2    rs3    rs4
ind1    TT    GG    GG    TT
ind2    TT    GG    GG    TT
ind3    TT    GG    GG    TT
ind4    AA    GG    GG    TT
ind5    AT    GG    GG    TT
ind6    TT    GG    GG    TT
ind7    AT    GG    GG    TT
ind8    AT    GG    GG    TT
ind9    AT    GG    GG    TT
ind10    AT    GG    GG    TT
ind11    AA    CC    GG    TT
ind12    TT    CG    GG    TT
ind13    AA    GG    GA    TT
ind14    AT    GG    GG    TT
ind15    TT    GC    GG    CC
ind16    AT    CC    AA    CT
ind17    AT    GG    AG    TC
ind18    AT    CG    AG    TT
ind19    AT    CG    GG    TT
ind20    AA    GC    GG    TT
ind21    TT    CC    AG    TT
ind22    AA    CG    AA    TT
ind23    AT    GG    GA    TC
ind24    TT    GG    GG    TT
ind25    AT    GC    GG    TT
ind26    AT    CC    AA    CC
ind27    AT    GG    AG    CT
ind28    AT    CG    AG    TC
ind29    AT    CG    GG    TT
ind30    AT    GC    GG    TT


id是人的编号,rs1, rs2,rs3,rs4是变量。每个变量是2个字母的组合,而且这2个字母一定是A T C G中的2个。比如第一列是A和T的组合。我想数出来每一列中哪个字母为少数字母,然后该列中2个少数字母的组合=2,含有一个少数字母=1,不含少数字母=0。比如第一列A字母数少于T字母数,然后所有的AA=2,AT=1,TA=1,TT=0。另外3列也是如此。我目前已经有SAS macro可以用,但是有点复杂。希望版上大牛能提供一个简洁高效的代码可用。

最佳答案

jingju11 查看完整内容

Can we count like that: JingJu
关键词:Macro IND acr CRO Mac
沙发
jingju11 发表于 2013-11-27 05:12:07 |只看作者 |坛友微信交流群
Can we count like that: JingJu
  1. data have2;
  2.         array x[4] $1. _temporary_;
  3.         array nx[4]  _temporary_;       
  4.         do _n_ =1 by 1 until(Eof);
  5.                 set have end =Eof;
  6.                 array rs[4] ;
  7.                 if _n_ =1 then do i =1 to 4;
  8.                         x[i] =substrn(rs[i],1,1);
  9.                         end;
  10.                 do j =1 to 4;
  11.                         do i =1 to 2;
  12.                                 nx[j] ++(ifn(substrn(rs[j],i,1)=x[j],1,-1));
  13.                                 end;
  14.                         end;
  15.                 end;
  16.         array ind_rs[4];  
  17.         do _n_ =1 by 1 until(Eof2);
  18.                 set have end =Eof2;
  19.                 do i =1 to 4;
  20.                         ind_rs[i] =ifn(nx[i] <0, count(rs[i],strip(x[i])), 2-count(rs[i],strip(x[i])));
  21.                         end;
  22.                 output;
  23.                 end;
  24.         drop i j;
  25.         run;
复制代码
已有 3 人评分学术水平 热心指数 信用等级 收起 理由
yuerqieqie + 1 + 1 + 1 精彩帖子
Eternal0601 + 5 + 5 + 5 精彩帖子
hopewell + 5 + 5 + 5 我很赞同

总评分: 学术水平 + 11  热心指数 + 11  信用等级 + 11   查看全部评分

使用道具

藤椅
statistics_qin 发表于 2013-11-27 10:19:26 |只看作者 |坛友微信交流群
data a;
input id $ rs1$ rs2$ rs3$ rs4$;
cards;
ind1    TT    GG    GG    TT
ind2    TT    GG    GG    TT
ind3    TT    GG    GG    TT
ind4    AA    GG    GG    TT
ind5    AT    GG    GG    TT
ind6    TT    GG    GG    TT
ind7    AT    GG    GG    TT
ind8    AT    GG    GG    TT
ind9    AT    GG    GG    TT
ind10    AT    GG    GG    TT
ind11    AA    CC    GG    TT
ind12    TT    CG    GG    TT
ind13    AA    GG    GA    TT
ind14    AT    GG    GG    TT
ind15    TT    GC    GG    CC
ind16    AT    CC    AA    CT
ind17    AT    GG    AG    TC
ind18    AT    CG    AG    TT
ind19    AT    CG    GG    TT
ind20    AA    GC    GG    TT
ind21    TT    CC    AG    TT
ind22    AA    CG    AA    TT
ind23    AT    GG    GA    TC
ind24    TT    GG    GG    TT
ind25    AT    GC    GG    TT
ind26    AT    CC    AA    CC
ind27    AT    GG    AG    CT
ind28    AT    CG    AG    TC
ind29    AT    CG    GG    TT
ind30    AT    GC    GG    TT
;
run;

data b;
        set a;
                a1=compress(rs1,'A','k');
                l1a=length(a1);
                t1=compress(rs1,'T','k');
                l1t=length(t1);
                c2=compress(rs2,'C','k');
                l2c=length(c2);
                g2=compress(rs2,'G','k');
                l2g=length(g2);
                a3=compress(rs3,'A','k');
                l3a=length(a3);
                g3=compress(rs3,'G','k');
                l3g=length(g3);
                c4=compress(rs4,'C','k');
                l4c=length(c4);
                t4=compress(rs4,'T','k');
                l4t=length(t4);
        if a1='' then l1a=0;
        if t1='' then l1t=0;
        if c2='' then l2c=0;
        if g2='' then l2g=0;
        if a3='' then l3a=0;
        if g3='' then l3g=0;
        if c4='' then l4c=0;
        if t4='' then l4t=0;
run;

proc sql;
        create table bb as
        select  sum(l1a) as l1a,sum(l1t) as l1t,sum(l2c) as l2c,sum(l2g) as l2g,
                        sum(l3a) as l3a,sum(l3g) as l3g,sum(l4c) as l4c,sum(l4t) as l4t
        from b
        ;
quit;

/*bb中可以看出rs1, rs2,rs3,rs4少数字母分别为:a c a c*/

data result;
        set b;
        if a1='AA' then col1=2;
                else if a1='A' then col1=1;
                        else if a1='' then col1=0;
        if c2='CC' then col2=2;
                else if c2='C' then col2=1;
                        else if c2='' then col2=0;
        if a3='AA' then col3=2;
                else if a3='A' then col3=1;
                        else if a3='' then col3=0;
        if c4='CC' then col4=2;
                else if c4='C' then col4=1;
                        else if c4='' then col4=0;
        keep id rs1 rs2 rs3 rs4 a1 col1 c2 col2 a3 col3 c4 col4;
run;



/*id是人的编号,rs1, rs2,rs3,rs4是变量。每个变量是2个字母的组合,而且这2个字母一定是A T C G中的2个。
比如第一列是A和T的组合。我想数出来每一列中哪个字母为少数字母,然后该列中2个少数字母的组合=2,
含有一个少数字母=1,不含少数字母=0。
比如第一列A字母数少于T字母数,然后所有的AA=2,AT=1,TA=1,TT=0。另外3列也是如此。*/

使用道具

板凳
statistics_qin 发表于 2013-11-27 10:20:36 |只看作者 |坛友微信交流群
statistics_qin 发表于 2013-11-27 10:19
data a;
input id $ rs1$ rs2$ rs3$ rs4$;
cards;
我是菜鸟,不要笑啊

使用道具

报纸
lchw001 发表于 2013-11-27 11:44:26 |只看作者 |坛友微信交流群
statistics_qin 发表于 2013-11-27 10:20
我是菜鸟,不要笑啊
谢谢!您的想法很好。问题是如果我有1000个变量怎么能自动recode而不用手动一个一个输入。

使用道具

地板
jingju11 发表于 2013-11-27 11:59:59 |只看作者 |坛友微信交流群
the problem is no rule for the two letters having equal counts. JingJu

使用道具

7
statistics_qin 发表于 2013-11-27 12:08:45 |只看作者 |坛友微信交流群
lchw001 发表于 2013-11-27 11:44
谢谢!您的想法很好。问题是如果我有1000个变量怎么能自动recode而不用手动一个一个输入。
用do loop来定义数组,试试看

使用道具

8
hopewell 发表于 2013-11-27 15:43:17 |只看作者 |坛友微信交流群
  1. data out;
  2.     length _maxchar $1;
  3.     declare hash h(hashexp:4);
  4.     rc=h.defineKey('_rsid');
  5.     rc=h.defineData('_rsid','a','t','c','g','_maxchar');
  6.     rc=h.defineDone();
  7.     call missing(_rsid,a,t,c,g,_maxchar);
  8.     array rs{4} $;
  9.     array score{4} (4*2);
  10.     array atcg a t c g;
  11.     do until(last);
  12.         set raw end=last;
  13.         do _rsid=1 to dim(rs);
  14.             rc=h.find();
  15.             do _charid=1 to 2;
  16.                 atcg(indexc('ATCG',substr(rs(_rsid),_charid,1)))+1;
  17.                 _maxn=max(of atcg(*));
  18.                 do _atcgid=1 to 4;
  19.                     if atcg(_atcgid)=_maxn then do;
  20.                         _maxchar=upcase(vname(atcg(_atcgid)));
  21.                         continue;
  22.                     end;
  23.                 end;
  24.             end;
  25.             if rc=0 then rc=h.replace();
  26.             else rc=h.add();
  27.             call missing(a,c,g,t);
  28.         end;
  29.     end;
  30.     call missing(last);
  31.     do until(last);
  32.         set raw end=last;
  33.         do _rsid=1 to dim(rs);
  34.             rc=h.find();
  35.             score(_rsid)=2-(count(rs(_rsid),_maxchar));
  36.         end;
  37.         output;
  38.     end;
  39.     drop _: rc a t c g;
  40. run;
复制代码
已有 3 人评分学术水平 热心指数 信用等级 收起 理由
yuerqieqie + 1 + 1 + 1 精彩帖子
Eternal0601 + 5 + 5 + 5 精彩帖子
jingju11 + 5 + 5 + 5 精彩帖子

总评分: 学术水平 + 11  热心指数 + 11  信用等级 + 11   查看全部评分

观钓颇逾垂钓趣 种花何问看花谁

使用道具

9
邓贵大 发表于 2013-11-27 23:36:03 |只看作者 |坛友微信交流群
yet another 菜鸟版
  1. data a;
  2. input id $ rs1$ rs2$ rs3$ rs4$;
  3. cards;
  4. ind1    TT    GG    GG    TT
  5. ind2    TT    GG    GG    TT
  6. ind3    TT    GG    GG    TT
  7. ind4    AA    GG    GG    TT
  8. ind5    AT    GG    GG    TT
  9. ind6    TT    GG    GG    TT
  10. ind7    AT    GG    GG    TT
  11. ind8    AT    GG    GG    TT
  12. ind9    AT    GG    GG    TT
  13. ind10    AT    GG    GG    TT
  14. ind11    AA    CC    GG    TT
  15. ind12    TT    CG    GG    TT
  16. ind13    AA    GG    GA    TT
  17. ind14    AT    GG    GG    TT
  18. ind15    TT    GC    GG    CC
  19. ind16    AT    CC    AA    CT
  20. ind17    AT    GG    AG    TC
  21. ind18    AT    CG    AG    TT
  22. ind19    AT    CG    GG    TT
  23. ind20    AA    GC    GG    TT
  24. ind21    TT    CC    AG    TT
  25. ind22    AA    CG    AA    TT
  26. ind23    AT    GG    GA    TC
  27. ind24    TT    GG    GG    TT
  28. ind25    AT    GC    GG    TT
  29. ind26    AT    CC    AA    CC
  30. ind27    AT    GG    AG    CT
  31. ind28    AT    CG    AG    TC
  32. ind29    AT    CG    GG    TT
  33. ind30    AT    GC    GG    TT
  34. ;

  35. proc transpose data=a out=b;
  36.         by id notsorted;
  37.         var rs1--rs4;
  38. data c;
  39.         set b;
  40.         chr = char(COL1, 1);
  41.         output;
  42.         chr = char(COL1, 2);
  43.         output;

  44. proc sql;
  45. create table d as
  46.         select _NAME_, chr, count(*) as count
  47.                 from c
  48.                 group by _NAME_, chr
  49.                 order by _NAME_, chr, count;
  50. quit;
  51. data e;
  52.         set d;
  53.         by _NAME_;
  54.         rank=first._NAME_;

  55. proc sql;
  56. create table f as
  57.         select c.*, e.rank
  58.         from c join e on c._NAME_=e._NAME_ and c.chr=e.chr;
  59. create table g as
  60.         select id, _NAME_, COL1, sum(rank) as rank
  61.         from f
  62.         group by id, _NAME_, COL1;
  63. quit;
  64. proc transpose data=g out=h;
  65.         id _NAME_;
  66.         by id;
  67.         var COL1;
  68. proc transpose data=g out=i prefix=ind_;
  69.         id _NAME_;
  70.         by id;
  71.         var rank;
  72. data j;
  73.         merge h i;
  74.         by id;
  75.         drop _NAME_;
  76. run;
复制代码
已有 1 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
webgu + 40 + 40 + 2 + 3 + 3 精彩帖子

总评分: 经验 + 40  论坛币 + 40  学术水平 + 2  热心指数 + 3  信用等级 + 3   查看全部评分

Be still, my soul: the hour is hastening on
When we shall be forever with the Lord.
When disappointment, grief and fear are gone,
Sorrow forgot, love's purest joys restored.

使用道具

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

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-28 15:41