【问题标题】:SAS: Do-loop and ArraySAS:循环和数组
【发布时间】:2014-05-08 17:38:52
【问题描述】:

我有一个按家庭组织的人员记录数据集。

  • 序列号:户号,同一户的成员有相同的序列号
  • 人数:这个家庭的人数
  • Pernum:分配给每个家庭中每个人的唯一编号
  • MOMLOC:显示此人的母亲是谁(按年数)在家庭中,0 表示家庭中没有此人的母亲
  • POPLOC:每个人的父亲都一样
  • SPLOC:每个人的配偶都一样
  • RELATE:人与户主的关系,1=户主,2=配偶,3=孩子,4=其他

目标是创建一个名为 NCH 的新变量,如果一个人年满 65 岁,并且 1 表示与儿子同住 2 表示与女儿同住 3 表示与儿子和女儿一起生活 .意思是不带孩子住

我认为带有 do 循环的数组应该能够完成此操作,但我在 SAS 中执行此操作的经验很少。有谁知道如何做到这一点?

【问题讨论】:

  • 1.这似乎是 PROC SQL 的完美案例,而不是 DATA 步骤。 2.究竟应该如何根据您描述的数据确定孩子的性别?
  • 这个问题太笼统了。尝试自己解决它,并询问您是否对它的某些方面有疑问。 Stack Overflow 不是一个“为你工作”的网站。
  • 抱歉,每个人的性别和年龄也包括在内。乔,嗯,我想具体的问题是,你如何告诉 SAS 重复执行一个动作,通过家庭序列,同时将一个人的 MOMLOC 或 POPLOC 与家庭中妈妈或爸爸的 PERNUM 匹配。我猜这可能是一个介绍性问题,但显然我在这里发布它是因为我没有人可以问。

标签: arrays loops sas


【解决方案1】:

我想出了两种解决方案,一种使用 proc sql,另一种使用数据步骤。这是proc sql解决方案:

proc sql;
    create table new as 
    select *, 
        case when 'M' in (select b.sex from people as b where a.serial=b.serial 
            and (a.pernum = b.momloc or a.pernum = b.poploc)) 
            then 1 else 0 end as son,
        case when 'F' in (select c.sex from people as c where a.serial=c.serial 
            and (a.pernum = c.momloc or a.pernum = c.poploc))
            then 1 else 0 end as daughter,
        case when calculated son = 1 and calculated daughter = 0 then 1
            when calculated son = 0 and calculated daughter = 1 then 2
            when calculated son = 1 and calculated daughter = 1 then 3
            else .
            end as nch
    from people as a
    where age >= 65;
quit;

“case”表达式类似于常规 SAS 中的“if then”。主要查询是针对表 people,它被赋予了 a 的“别名”。括号中的选择语句称为子查询。他们使用别名 b 和 c 查询表 people。它们的子查询是检查天气是否存在男性(或女性),其中 a 中的序列等于 b(或 c)中的序列,a 中的 pernum 等于 b(或 c)中的 momloc 或 poploc。

这里是数据步解决方案:

data test;
    set people;
    where age >= 65;
    son = 0;
    daughter = 0;
    do i = 1 to nobs;
        set people (keep=serial momloc poploc sex age 
            rename=(serial=serial1 momloc=momloc1 poploc=poploc1 sex=sex1 age=age1)) 
            point=i nobs=nobs;
        if sex1 = 'M' and serial=serial1 and (pernum = momloc1 or pernum = poploc1) 
            then son = 1;
        if sex1 = 'F' and serial=serial1 and (pernum = momloc1 or pernum = poploc1) 
            then daughter = 1;
    end;
    if son = 1 and daughter = 0 then nch = 1;
    else if son = 0 and daughter = 1 then nch = 2;
    else if son = 1 and daughter = 1 then nch = 3;
    else nch = .;
    drop serial1 momloc1 poploc1 sex1 age1 son daughter;
run;

这里的数据步骤是一次循环遍历一组“人”记录,并且对于每条记录,它循环遍历同一数据集“人”的每条记录。 “nobs”为“people”中的观察次数,“point”为每条记录对应的次数。

【讨论】:

  • 运行需要很长时间(几个小时),因为数据集太大了,但我对其进行了子集化并尝试了代码,结果完美。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多