为不存在的观测值生成观测值

时间:2016-07-14 08:21:22

标签: sas missing-data

我目前正面临SAS问题。我正在撰写关于职业伤害和这种事故造成的工资损失的硕士论文。我拥有一个包含特定人口月工资信息的数据集。数据集包含每个人的特定标识符以及一系列背景信息,如教育,性别等。如果个人已收到特定月份的工资支付,则他或她在我的特定月份的数据集中,具有上述条件 - 提到的信息。如果该人未在特定月份收到工资(例如,由于失业,假期,疾病等),则该人在该特定月份的数据集中找不到 - 即使该人可能已收到工资付款无论是在上个月还是在下个月。因此,例如,一个工作了整整一年的人在数据集中有12个观察值。如果某人由于某种原因没有工作2个月,那个人只有10个观察。

如果我不处理这个问题,我很可能会在估算中得到正偏差。一个人可能在某个月内遭受职业伤害,然后在一个月后返回,该人因疾病而缺席的月份应构成零工资支付,但仍包含“背景”信息。

我上传了一个数据集示例,可以在这里找到:

https://www.dropbox.com/s/0zkr0430menotdf/Data.xlsx?dl=0

该数据包含三个人(1,2,3),其中包含工资信息,教育组,性别。具有标识符2的人没有收到第8个月的付款,因此对该月没有任何观察。

我不知道如何制作SAS程序,这将填写该人的信息。我想对第2个月的第8个月进行一次新的观察,工资支付为零但是上个月的其他变量的滞后信息。在我的原始数据集中,我有几千人,其中一些潜在的可能有多个不存在的工资信息。

2 个答案:

答案 0 :(得分:0)

最简单的方法是构建一个master表,如果您的数据完美,它将包含月份和个人的每个组合。获得此数据集后,您就可以加入错误的实际数据,无论数据丢失,都可以获得完整视图。

不需要滞后信息,因为无论如何所有列都在那里。

这是一个虚拟的例子(我称之为用户而不是个人)

/* table with 1-12 that represents months ids*/
data months(drop=i);
do i=1 to 12;
 month=i;
 output;
end;
run;
/* table with unique user ids*/
    data users;
user_id = 1000;gender='M';output;
user_id = 1001;gender='F';output;
run;

/* Your data*/
data my_data;
input user_id month salary;
cards;
1001 1 1500
1001 2 1500
1001 3 1500
1001 4 1500
1001 5 1500
1001 6 1500
1001 7 1500
1001 8 1500
1001 9 1500
1001 10 1500
1001 11 1500
1001 12 1500
1000 1 800
1000 2 800
1000 3 800
1000 4 800
;
run;

/* Step1: Build a full combination of (cartesian join) of months & users
  In this case is 12 months x 2 users = 24 records
*/
proc sql;
create table master_tbl as
    select * from months, users;
quit;

/* Step2: Left join your 'faulty' data against the master table to get a full view
for each user */

proc sql;
create table full_view as
Select t1.*, t2.salary from master_tbl t1 left join my_data t2
                            on t1.user_id = t2.user_id and
                               t1.month = t2.month;
quit;

full_view数据集将包含非缺失和丢失的案例。当工资信息丢失时,您可以检测到丢失的案例。

注意:如果您认为wage变量也有问题,则在数据中创建一个虚拟标记(f = 1)并将其带入full_view数据集以突出显示缺失的数据。

编辑1: 要替换数据,您可以这样做:

data full_view;
 set full_view;
 if salary = . then do;
   salary = 0;
   salary_ind = (salary = 0); /*Dummy to keep track of what you have imputed*/
end;
run;

希望有所帮助

答案 1 :(得分:0)

与Altons的解决方案非常相似,一个区别是我在PROC SQL步骤中替换了工资的缺失值。

/*Load the data*/
PROC SQL;
    CREATE TABLE have AS 
        SELECT t1.Identifier, 
            t1.Month, 
            t1.Wage, 
            t1.'education category'n, 
            t1.gender
        FROM WORK.DATA t1
            ORDER BY identifier, month;
QUIT;


/*Create a dataset with 12 observations of each id.*/
data a;
    do i=1 to 3;
        do j=1 to 12;
            identifier=i;
            month=j;
            output;
        end;
    end;

    drop i j;
run;


/*Merge the dataset above with the original dataset, replacing missing values of wage with 0.*/
proc sql;
    create table ab as
        select a.*, coalesce(b.wage,0) as wage, b.'education category'n, b.gender
            from a
                left join have as b on a.identifier=b.identifier and a.month=b.month;
quit;


/*Use the update statement to carry forward previous non-missing values.*/
data want;
    update a (obs=0) ab;
    by identifier;
    output;
run;