SAS中文论坛

标题: sas一个取最大值的问题[求助,急!!!] [打印本页]

作者: shiyiming    时间: 2010-8-23 10:56
标题: sas一个取最大值的问题[求助,急!!!]
小弟菜鸟,为了做一个research在硬着头皮学SAS,看了不少书发现也不管用(根本不够用阿。。。)

现在有个棘手的问题,求好心达人帮忙:

有一张表,里面有很多投资公司在不同年份投资了不同行业(总共10个行业),比如甲公司在A行业04年投了2次08年投了3次09年投了1次,D行业08年投了8次,F行业如何如何依次类推等等。
甲公司XX年在A行业投了n次为一个Observation(那些没投资的dummy=0我也都有了)。

现在我要得到这些公司在这些年份之前(比如数据从1980年开始算的是1994年的话就是该公司从1980年到1994年间投资在A/B/C/...行业的数量)所有的投资行业中哪个最多,哪个第二多,并且算出分别投了多少次。
如果这个太麻烦算出当年这个公司投的最多第二多是哪个行业也成(我自己再想办法推到在这年以前的情况)。

我是想要当年这个TOP Industry变成一个新的Variable,然后相应的投资次数再一个新的Var(所以说甲公司XX年所有的这两个Var都是这个Industry和相应的投资数)。
依此类推SECOND Industry。

非常急,在线等,求助,谢谢。
作者: shiyiming    时间: 2010-8-23 11:33
标题: Re: sas一个取最大值的问题[求助,急!!!]
如果你的意思是比较同一公司不同行业的排名
先sort
然后
[code:2gtk73c5]
proc freq data=test order=freq;
by company;  
tables industry;
weight times;
run;
[/code:2gtk73c5]
作者: shiyiming    时间: 2010-8-23 12:01
标题: Re: sas一个取最大值的问题[求助,急!!!]
我的表达能力果然还是很差诶,不好意思。。。

我是想要这个TOP Industry变成一个新的Variable,然后投资次数再一个新的Var。
依此类推SECOND Industry。

而且这段代码貌似得到的是总的一个FREQ是吧?
我想要得到的这两个VAR都是关于每年的呢?
作者: shiyiming    时间: 2010-8-23 13:47
标题: Re: sas一个取最大值的问题[求助,急!!!]
[quote:19pzuka1]现在我要得到这些公司在[color=#FF0000:19pzuka1]这些年份之前[/color:19pzuka1]所有的投资行业中哪个最多[/quote:19pzuka1]
"这些年份之前"是什么意思,是每年的上一年还是特指的一年?
作者: shiyiming    时间: 2010-8-23 13:55
标题: Re: sas一个取最大值的问题[求助,急!!!]
就是比如数据从1980年开始,我算1994年的这个值算的是从1980年到1994年间所有的投资在A/B/C...行业中的数量.
作者: shiyiming    时间: 2010-8-23 15:26
标题: Re: sas一个取最大值的问题[求助,急!!!]
你是要对每一个日期前算总量么?还是固定时间段内的?还是所有的?另外,你的数据是year company industryA industryB ......这样的么?

你还是给几个example data说的会比较清楚。
作者: shiyiming    时间: 2010-8-23 15:53
标题: Re: sas一个取最大值的问题[求助,急!!!]
我不确定是否实现了在并列值中随机排序,你测试看看吧
[code:2x1rsbjo]data raw;
    length COMPANY $1 YEAR $4 INDUSTRY $40;
    input;
    COMPANY=scan(_infile_,1,' ');
    YEAR=scan(_infile_,2,' ');
    INDUSTRY=substr(_infile_,8,anydigit(_infile_,8)-9);
    COUNT=input(scan(_infile_,-1,' '),best.);
datalines;
A 1999 Communications and Media 1
A 1999 Computer Software and Services 1
A 1999 Internet Specific 5
A 2000 Communications and Media 1
A 2000 Computer Software and Services 7
A 2000 Internet Specific 1
A 2001 Communications and Media 1
A 2001 Computer Software and Services 1
A 2001 Internet Specific 1
B 1999 Biotechnology 8
B 1999 Communications and Media 7
B 1999 Computer Hardware 2
B 1999 Computer Software and Services 23
B 1999 Consumer Related 23
B 1999 Industrial/Energy 12
B 1999 Internet Specific 21
B 1999 Medical/Health 7
B 1999 Other Products 34
B 1999 Semiconductors/Other Elect. 5
B 2000 Biotechnology 13
B 2000 Communications and Media 14
B 2000 Computer Hardware 5
B 2000 Computer Software and Services 34
B 2000 Consumer Related 12
B 2000 Industrial/Energy 19
B 2000 Internet Specific 56
B 2000 Medical/Health 11
B 2000 Other Products 25
B 2000 Semiconductors/Other Elect. 3
;
proc transpose data=raw out=temp(drop=_name_);
    var count;
    by company year;
    id industry;
run;
data temp(drop=i);
    do _n_=1 by 1 until(last.company);
        set temp;
        by company;
        array industry_count_ {*} _numeric_;
        array temp {10} _temporary_;
        do i=1 to dim(industry_count_);
            industry_count_(i)=sum(ifn(missing(industry_count_(i)),0,industry_count_(i)),temp(i));
            temp(i)=industry_count_(i);
        end;
        output;
    end;
run;
data temp(keep=company year industry_count_1 industry_count_2 industry_name_1 industry_name_2);
    set temp;
    array temp {*} _numeric_;
    array industry_count_ {10};
    array industry_name_ {10} $32;
    flag=ceil(ranuni(0)*10);
    do i=1 to dim(industry_count_);
        j=i+ifn(i ge flag,-flag,10-flag)+1;
        industry_count_(j)=temp(i);
        call vname(temp(i),industry_name_(j));
    end;
    do i=dim(industry_count_)-1 to 1 by -1;
        do j=1 to i;
            if industry_count_(j+1) gt industry_count_(j) then do;
                temp_num=industry_count_(j);
                industry_count_(j)=industry_count_(j+1);
                industry_count_(j+1)=temp_num;
                temp_chr=industry_name_(j);
                industry_name_(j)=industry_name_(j+1);
                industry_name_(j+1)=temp_chr;
            end;
        end;
    end;
run;[/code:2x1rsbjo]
作者: shiyiming    时间: 2010-8-23 17:28
标题: Re: sas一个取最大值的问题[求助,急!!!]
不好意思 第一次上来提问 问得辞不达意。。。
我既要算每年该公司的情况,也要算这年前所有的情况。
楼上大侠的数据结构貌似是对的,代码…我要好好研究学习下呀~

贴个sample上来吧:
COMPANY        YEAR        INDUSTRY        COUNT
A        1999        Communications and Media        1
A        1999        Computer Software and Services        1
A        1999        Internet Specific        5
A        2000        Communications and Media        1
A        2000        Computer Software and Services        7
A        2000        Internet Specific        1
A        2001        Communications and Media        1
A        2001        Computer Software and Services        1
A        2001        Internet Specific        1
B        1999        Biotechnology        8
B        1999        Communications and Media        7
B        1999        Computer Hardware        2
B        1999        Computer Software and Services        23
B        1999        Consumer Related        23
B        1999        Industrial/Energy        12
B        1999        Internet Specific        21
B        1999        Medical/Health        7
B        1999        Other Products        34
B        1999        Semiconductors/Other Elect.        5
B        2000        Biotechnology        13
B        2000        Communications and Media        14
B        2000        Computer Hardware        5
B        2000        Computer Software and Services        34
B        2000        Consumer Related        12
B        2000        Industrial/Energy        19
B        2000        Internet Specific        56
B        2000        Medical/Health        11
B        2000        Other Products        25
B        2000        Semiconductors/Other Elect.        3
作者: shiyiming    时间: 2010-8-24 17:24
标题: Re: sas一个取最大值的问题[求助,急!!!]
我用前辈给的代码貌似的确完成了排序工作(虽然最后那小段琢磨不出什么意思望指点小弟。。。)。

一个新问题(应该算个小问题):
如果出现并列(比如甲公司在XX年在A和B分别投了15次并列最多)怎么让它随机一个第一,一个第二(现在的情况默认编号大的第一,小的第二,分析的时候应该会不合理的)?

大谢!
[quote="hopewell":3gh3uac0]修改中...[/quote:3gh3uac0]
作者: shiyiming    时间: 2010-8-25 01:04
标题: Re: sas一个取最大值的问题[求助,急!!!]
to hopewell
呃。。。大神阿,怎么和上次的那块砖长得很不同了涅orz
这个我又要研究好一阵了估计
其实上次的那个方法已经把排序问题解决了貌似,只差最后一步并列情况随机的工作了。。。

诶丫丫,又要满眼天书了@@
好弱。。。
作者: shiyiming    时间: 2010-8-25 20:00
标题: Re: sas一个取最大值的问题[求助,急!!!]
不大行呃。。。结果有问题,然后也看不大懂程序所以也不知道怎么调。。。
其实上次的那个程序真的只差最后的一步随机选并列的情况了。。。
作者: shiyiming    时间: 2010-8-25 20:19
标题: Re: sas一个取最大值的问题[求助,急!!!]
啥问题? 排错了还是不随机?
作者: shiyiming    时间: 2010-8-25 21:12
标题: Re: sas一个取最大值的问题[求助,急!!!]
排错。。。我还在想办法找问题,但是水平实在有限@@
搞不大清为什么这个版本和前面那个差别这么大。。。

509  data temp(drop=i);
510      do _n_=1 by 1 until(last.company);
511          set temp;
512          by company;
513          array industry_count_ {*} _numeric_;
514          array temp {10} _temporary_;
515          do i=1 to dim(industry_count_);
516              industry_count_(i)=sum(ifn(missing(industry_count_(i)),0,industry_count_(i)),temp(i))
516! ;
517              temp(i)=industry_count_(i);
518          end;
519          output;
520      end;
521  run;

ERROR: Array subscript out of range at line 516 column 90.

会不会因为我手上这个表太大了不能用array?将近30w行的数据。。。
作者: shiyiming    时间: 2010-8-25 21:15
标题: Re: sas一个取最大值的问题[求助,急!!!]
然后industry_name_1全部显示是year,industry_count_1全部等于year的值。
作者: shiyiming    时间: 2010-8-25 22:45
标题: Re: sas一个取最大值的问题[求助,急!!!]
把year改成字符变量估计就对了
作者: shiyiming    时间: 2010-8-26 01:54
标题: Re: sas一个取最大值的问题[求助,急!!!]
嗯!的确~大谢前辈!
不过还有最后一个小问题,industry_count的计数器一直在加(没有按照公司分开在换公司的时候计数器没有清零)导致最后一直加到了6000多。
应该怎么改一下原来的代码?
作者: shiyiming    时间: 2010-8-26 05:50
标题: Re: sas一个取最大值的问题[求助,急!!!]
我跟版主是一个师傅教出来的。
作者: shiyiming    时间: 2010-8-26 07:22
标题: Re: sas一个取最大值的问题[求助,急!!!]
多谢老猪,慢慢看 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
作者: shiyiming    时间: 2010-8-26 20:14
标题: Re: sas一个取最大值的问题[求助,急!!!]
大谢这位前辈!
这段程序连我这种水平都看懂了,感动:)
主要问题都大致解决了~
受教了。

[quote=&quot;死猪头&quot;:iphbomve]我跟版主是一个师傅教出来的。
[code:iphbomve]
data raw;
    length COMPANY $1 YEAR $4 INDUSTRY $40;
    input;
    COMPANY=scan(_infile_,1,' ');
    YEAR=scan(_infile_,2,' ');
    INDUSTRY=substr(_infile_,8,anydigit(_infile_,8)-9);
    COUNT=input(scan(_infile_,-1,' '),best&#46;);
datalines;
A 1999 Communications and Media 1
A 1999 Computer Software and Services 1
A 1999 Internet Specific 5
A 2000 Communications and Media 1
A 2000 Computer Software and Services 7
A 2000 Internet Specific 1
A 2001 Communications and Media 1
A 2001 Computer Software and Services 1
A 2001 Internet Specific 1
B 1999 Biotechnology 8
B 1999 Communications and Media 7
B 1999 Computer Hardware 2
B 1999 Computer Software and Services 23
B 1999 Consumer Related 23
B 1999 Industrial/Energy 12
B 1999 Internet Specific 21
B 1999 Medical/Health 7
B 1999 Other Products 34
B 1999 Semiconductors/Other Elect&#46; 5
B 2000 Biotechnology 13
B 2000 Communications and Media 14
B 2000 Computer Hardware 5
B 2000 Computer Software and Services 34
B 2000 Consumer Related 12
B 2000 Industrial/Energy 19
B 2000 Internet Specific 56
B 2000 Medical/Health 11
B 2000 Other Products 25
B 2000 Semiconductors/Other Elect&#46; 3
;

proc sort data=raw out=zhutou;
        by company industry year;
run;
data sizhutou(drop=count);
        do until (last&#46;industry);
                do until(last&#46;year);
                        set zhutou;
                        by company industry year;
                        acum_count = sum(acum_count, count);
                end;
                random_number = ranuni(12345);
                output;
        end;
run;
proc sort data=sizhutou out=zhupo;
        by company year descending acum_count random_number;
run;
data zhuzai;
        do _n_=1 by 1 until(last&#46;year);
                set zhupo;
                by company year;
                if _n_ &lt; 3 then output;
        end;
run;
[/code:iphbomve][/quote:iphbomve]
作者: shiyiming    时间: 2010-8-27 01:46
标题: 一个新的小问题
噢,BTW,这个程序有个前提是每个公司的这些年份都是连着的(你看我给是1999-2001和1999-2000),如果中间跳开(实际情况是数据从1958-2010间断断续续有)那个acum_count就会有问题:

只有有投资发生的年份里这个行业才有这个值,但是事实上比如1999年公司在这个行业A里投了100次,次年没投到时在另一个行业B里投了1次,结果这个程序走出来的结果2000年前最多的行业就变成了B哪怕只有一次)。

我之前用过一个很复杂的办法把所有每个行业在没有投资事件发生的年份(从数据起止年间)里面都做了0,但是程序写得很纠结很低效(10个industry还好,如果再多点这个数据冗余就非常严重了),前辈们有没有好点的办法实现?

比如数据变成:
A 1989 Communications and Media 1
A 1997 Computer Software and Services 1
A 1999 Internet Specific 5
A 2000 Communications and Media 1
A 2000 Computer Software and Services 7
A 2000 Internet Specific 1
A 2001 Communications and Media 1
A 2001 Computer Software and Services 1
A 2008 Internet Specific 1
B 1994 Biotechnology 8
B 1999 Communications and Media 7
B 1999 Computer Hardware 2
B 1999 Computer Software and Services 23
B 1999 Consumer Related 23
B 1999 Industrial/Energy 12
B 1999 Internet Specific 21
B 1999 Medical/Health 7
B 1999 Other Products 34
B 1999 Semiconductors/Other Elect. 5
B 2000 Biotechnology 13
B 2000 Communications and Media 14
B 2000 Computer Hardware 5
B 2000 Computer Software and Services 34
B 2000 Consumer Related 12
B 2000 Industrial/Energy 19
B 2000 Internet Specific 56
B 2000 Medical/Health 11
B 2008 Other Products 25
B 2008 Semiconductors/Other Elect. 3
作者: shiyiming    时间: 2010-8-27 05:20
标题: Re: sas一个取最大值的问题[求助,急!!!]
猪头又上当了!
mz同学你说得不错,可以施采补之术
你只有几万行数据,不必担心冗余。
说来说去,问题还得靠你自己发现解决。
作者: shiyiming    时间: 2010-8-27 08:39
标题: Re: sas一个取最大值的问题[求助,急!!!]
越来越没耐心看这种描述不清的问题了。 <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
作者: shiyiming    时间: 2010-8-27 11:05
标题: Re: sas一个取最大值的问题[求助,急!!!]
真的太感谢你了:)
你的这个方法比我那个明显好。。。
基本问题都解决,受教了受教了!!!

[quote=&quot;死猪头&quot;:3uagxwrw]猪头又上当了!
mz同学你说得不错,可以施采补之术,在第一个proc sort后加
[code:3uagxwrw]
data zhutou(drop=last_year);
        do until (last&#46;company);
                do until(last&#46;industry);
                        set zhutou;
                        by company industry;
                end;
                last_year = max(year, last_year);
        end;

        do until (last&#46;company);
                do until(last&#46;industry);
                        set zhutou;
                        by company industry;
                        output;
                end;
                if year&lt;last_year then do;
                        year = last_year;
                        count=&#46;;
                        output;
                end;
        end;
run;

proc expand data=zhutou out=zhutou from=day;
        id year;
        by company industry;
        convert count/method=none;
run;
[/code:3uagxwrw]
也可以自行采补,将data sizhutou步换成
[code:3uagxwrw]
data sizhutou(drop=count year prev_year last_year rename=(year1=year));
        do until (last&#46;company);
                do until(last&#46;industry);
                        set zhutou;
                        by company industry;
                end;
                last_year = max(year, last_year);
        end;

        do until (last&#46;company);
                acum_count=0;
                do until(last&#46;industry);
                        set zhutou;
                        by company industry;
                 if not first&#46;industry then do year1=prev_year+1 to year-1;
                            random_number = ranuni(12345);
                                 output;
                         end;
                        acum_count = sum(acum_count, count);
                        year1 = year;
                        random_number = ranuni(12345);
                        output;
                        prev_year = year;
                end;
                do year1 = year+1 to last_year;
                        random_number = ranuni(12345);
                        output;
                end;
        end;
run;
[/code:3uagxwrw]
你只有几万行数据,不必担心冗余。
说来说去,问题还得靠你自己发现解决。[/quote:3uagxwrw]




欢迎光临 SAS中文论坛 (https://mysas.net/forum/) Powered by Discuz! X3.2