【问题标题】:Replicating values in SAS by group按组复制 SAS 中的值
【发布时间】:2019-07-25 15:53:42
【问题描述】:

我有一个数据集,其中包含测量结果和收集数据的具体日期。我想在几天之间复制这些值,直到最后一个测量日。例如,这里是复制前的数据:

           Measurement    Day
Subject1   .85            -1
Subject1   .86            1            
Subject1   .91            7            
Subject1   .83            9            
Subject2   .77            0            
Subject2   .82            5            
Subject2   .86            12           

我想修改上面的数据集,如下所示:

           Measurement    Day
Subject1   .85            -1
Subject1   .85            0
Subject1   .86            1
Subject1   .86            2
Subject1   .86            3
Subject1   .86            4
Subject1   .86            5 
Subject1   .86            6           
Subject1   .91            7
Subject1   .91            8            
Subject1   .83            9            
Subject2   .77            0
Subject2   .77            1
Subject2   .77            2
Subject2   .77            3
Subject2   .77            4       
Subject2   .82            5          
Subject2   .82            6
Subject2   .82            7     
Subject2   .82            8     
Subject2   .82            9     
Subject2   .82            10
Subject2   .82            11                      
Subject2   .86            12           

【问题讨论】:

    标签: arrays loops sas


    【解决方案1】:

    您可以通过将合并的数据偏移一行并省略by 语句来进行“前瞻合并”;

    (假设您的数据按主题和日期排序)

    数据合并1; 合并有 有 (rename=(day=nextday subject=nextsubject) drop=measurement firstobs=2) ; 如果 subject = nextsubject 然后 _day = day to nextday - 1 ; 输出 ; 结尾 ; 否则做; _day = 天; 输出 ; 结尾 ; drop day nextday next 主题; 重命名_day =天; 跑 ;

    【讨论】:

    • 酷。您可以使用单个 DO 循环,而无需 _DAY 变量。 do day = day by 1 until (day+1 > nextday);
    • 在第二次引用 HAVE 时需要 keep=day subject 数据集选项,以防止覆盖测量变量。
    【解决方案2】:

    考虑使用 helper 数据集扩展数据,然后使用前向填充左连接 merge

    data helper;
        set input (keep = Subject Day);
        by Subject;
        if not first.Subject and last.Subject;
    
        max_day = max(Day);
        day = 0;
        do until(day > max_day);
          output;
          day + 1;
        end;
    
        drop max_day;
    run;
    
    data output;
        merge helper (in=h)
              input (in=i);
        if h;
        by Subject Day;
    
        retain _k;
        if not missing(Measurement) then _k=Measurement;
        else if missing(Measurement) then Measurement=_k;
    
        if not missing(Measurement);
        drop _k;
    run;
    

    数据

    data input;
        infile datalines delimiter=',' DSD; 
        length subject $ 10;
    
        input subject measurement day;
        datalines;
    Subject1,.86,1 
    Subject1,.91,7 
    Subject1,.83,9 
    Subject2,.77,0 
    Subject2,.82,5 
    Subject2,.86,12
    ;
    

    输出

    Obs  subject   day   measurement 
    1   Subject1     1          0.86 
    2   Subject1     2          0.86 
    3   Subject1     3          0.86 
    4   Subject1     4          0.86 
    5   Subject1     5          0.86 
    6   Subject1     6          0.86 
    7   Subject1     7          0.91 
    8   Subject1     8          0.91 
    9   Subject1     9          0.83 
    10  Subject2     0          0.77 
    11  Subject2     1          0.77 
    12  Subject2     2          0.77 
    13  Subject2     3          0.77 
    14  Subject2     4          0.77 
    15  Subject2     5          0.82 
    16  Subject2     6          0.82 
    17  Subject2     7          0.82 
    18  Subject2     8          0.82 
    19  Subject2     9          0.82 
    20  Subject2     10         0.82 
    21  Subject2     11         0.82 
    22  Subject2     12         0.86 
    

    【讨论】:

    • 刚试过用这个。这导致受试者的最终体重成为下一个受试者的第一个体重。有什么办法可以解决这个问题?
    • 不确定我是否理解。如果您使用我包含的数据运行我的解决方案以实现可重复性,则输出将与您想要的结果相匹配,并具有不同的列顺序。也许您的实际数据与发布的示例不同。
    • 是的,我正在处理一个新的数据集。也许我应该更简洁:代码导致下一个主题的第一个数字被前一个主题的最终测量值覆盖。此外,如果“天”列中的数字为负数,则此方法无效。
    • 再一次,此解决方案符合您发布的所需结果。受试者 2 的第一条记录在第 0 天的测量值为 0.77,这与输入数据中的完全相同。您的样本不包括我可能会考虑在内的负面天数。将来,请发布接近实际数据!
    • 请运行我的可重现示例(首先运行 input 的数据部分,然后在顶部运行实际代码)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    相关资源
    最近更新 更多