楼主: fin168
2057 5

[有偿编程] 缺失值填补 [推广有奖]

  • 3关注
  • 1粉丝

大专生

8%

还不是VIP/贵宾

-

威望
0
论坛币
11 个
通用积分
0
学术水平
4 点
热心指数
4 点
信用等级
4 点
经验
220 点
帖子
26
精华
0
在线时间
46 小时
注册时间
2013-7-6
最后登录
2013-9-6

2500论坛币
有很多个SHEET,需要对SHEET里面的一列数据进行就近填补,数据如下:

obs .
1 .
2 566
3 .
4 .
5 .
6 .
7 .
8 .
9 .
10 .
11 998
12 .
.... .
n .

想达到如下目的:1)就近填补缺失值,整列都要填满。
2)如果是连续的缺失值,比如OBS3-OBS10,离上面近的用上面的值填补,离下面近的用下面的填补。
2)如果缺失值里离上下的值一样近,那么就用上面的填补。

跪求高手,2500论坛币相送。



最佳答案

moyunzheng 查看完整内容

用SQL,代码可能更加简单一些
关键词:缺失值填补 缺失值 500论坛币 sheet 0论坛币 count

回帖推荐

pobel 发表于3楼  查看完整内容

是不是这个意思: data test; do value=.,566,.,.,.,.,.,.,.,.,998,.,.,.,1200,.; origvalue=value; output; end; run; data test1; obs=_n_; set test; retain tmp num; flag=missing(value); *** Previous non-missing; if flag=0 then do; tmp=value; num=0; end; else if flag=1 then do; num+1; value=tmp; end; run; proc sort data=test1 ...

moyunzheng 发表于6楼  查看完整内容

沙发
moyunzheng 发表于 2013-7-8 10:09:23 |只看作者 |坛友微信交流群
用SQL,代码可能更加简单一些
  1. data test;
  2.         id=0;
  3.     do old_value=.,566,.,.,.,.,.,.,.,.,998,.,.,.,1200,.;
  4.                    id=id+1;
  5.            output;
  6.         end;
  7. run;

  8. proc sql noprint;
  9. create table result
  10.         as select * from (
  11.                 select distinct a.id,b.id as id_match,a.old_value,b.old_value as new_value
  12.                         from test as a,test as b
  13.                         where b.old_value ne .
  14.                         group by a.id
  15.                         having a.id=b.id or (abs(a.id-b.id)=min(abs(a.id-b.id)) ))
  16.         group by id
  17.         having id_match=min(id_match);
  18. quit;
复制代码

使用道具

藤椅
pobel 在职认证  发表于 2013-7-8 10:35:31 |只看作者 |坛友微信交流群
是不是这个意思:
data test;
    do value=.,566,.,.,.,.,.,.,.,.,998,.,.,.,1200,.;
           origvalue=value;
           output;
        end;
run;

data test1;
   obs=_n_;
   set test;
   retain tmp num;
   flag=missing(value);

   *** Previous non-missing;
   if flag=0 then do;
       tmp=value;
           num=0;
        end;
        else if flag=1 then do;
            num+1;
                value=tmp;
        end;
run;

proc sort data=test1;
  by descending obs;
run;

data test2;
    set test1;
        by descending obs;
        retain tmp1 num1 num2;
    *** Next non-missing;
        if flag=0 then do;
        tmp1=value;
                num1=0;
        end;
        else if flag=1 then do;
            if num1=0 then num2=int(num/2);
        num1+1;
        if num1 <= num2 and ^missing(tmp1) then value=tmp1;
                if missing(value) then value=tmp1;
        end;
        keep obs origvalue value;
run;

proc sort data=test2;  
    by obs;
run;
和谐拯救危机

使用道具

板凳
fin168 发表于 2013-7-8 11:06:48 |只看作者 |坛友微信交流群
pobel 发表于 2013-7-8 10:35
是不是这个意思:
data test;
    do value=.,566,.,.,.,.,.,.,.,.,998,.,.,.,1200,.;
这个应该能解决一个SHEET的问题,不过我的是很多个SHEET呢,那该怎么办呢

使用道具

报纸
fin168 发表于 2013-7-8 11:31:35 |只看作者 |坛友微信交流群
moyunzheng 发表于 2013-7-8 11:19
用SQL,代码可能更加简单一些
多个SHEET的话,如何处理

使用道具

地板
moyunzheng 发表于 2013-7-8 12:57:21 |只看作者 |坛友微信交流群
infile为输入的excel文件,outfile为输出的excel文件
需要修改的变量名为value,新生成的变量名为new_value,这个可以修改
测试过,可用。
  1. %macro xlread(infile=,outfile=);
  2. /**Assign a libname for excel sheet*/
  3. LIBNAME INXLS "&infile.";
  4. libname outxls "&outfile.";
  5. /***PART1 OF THE PROGRAM USE PROC SQL TO READ THE SHEET NAMES IN THE EXCEL SHEET
  6. SPECIFIED BY THE LIBNAME STATMENT ABOVE****/
  7. /**creating macro variables for the sheet**/
  8. proc sql noprint;
  9.         create table work.all_sheets
  10.                 as select strip(MEMNAME) as MEMNAME
  11.                 from sashelp.vtable
  12.                 where LIBNAME ='INXLS' and find(reverse(strip(memname)),"[        DISCUZ_CODE_0        ]quot;)=1;
  13.         /***Get total Number of Sheets***/
  14.         select count(distinct(MEMNAME)) into :nums_sheets
  15.                 from work.all_sheets ;
  16.         /**Get the sheet names with and without $ in to macro variables***/
  17.         select distinct(MEMNAME) into :v1 - :v%trim (%left(&nums_sheets.))
  18.                 from work.all_sheets ;
  19.         select distinct(substr(strip(MEMNAME),1,length(strip(MEMNAME))-1)) into :s1 - :s%trim (%left(&nums_sheets.))
  20.                 from work.all_sheets ;
  21.         Quit;
  22.         %put _all_;
  23. %do i=1 %to &nums_sheets.;
  24.         data work.sheet_temp work.sheet_temp2;run;
  25.         data work.sheet_temp;
  26.         set INXLS."&&v&i.."n;
  27.         id=_n_;
  28.         run;
  29.         proc sql noprint;
  30.         create table work.sheet_temp2
  31.                 as select * from (
  32.                         select distinct a.id,b.id as id_match,a.value as old_value,b.value as new_value
  33.                                 from work.sheet_temp as a,work.sheet_temp as b
  34.                                 where b.value ne .
  35.                                 group by a.id
  36.                                 having a.id=b.id or (abs(a.id-b.id)=min(abs(a.id-b.id)) ))
  37.                 group by id
  38.                 having id_match=min(id_match);
  39.         quit;
  40.         data outxls."&&s&i.."n;
  41.                 set work.sheet_temp2;
  42.                 run;
  43.         %end;
  44. libname inxls clear;
  45. libname outxls clear;
  46. %mend;
  47. %xlread(infile=d:\test.xls,outfile=d:\test2.xls);
复制代码

使用道具

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

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

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

GMT+8, 2024-4-28 19:04