【问题标题】:SAS to delete observations that meet condition within groupSAS删除符合组内条件的观察
【发布时间】:2020-10-21 20:28:16
【问题描述】:

我想删除Have数据集中满足以下所有条件的记录。 ID_num这里代表ID字段的3位部分

  • ID = Mxxx
  • 类型 = 血液
  • 位于以下任何记录之前每组(ID_num,药物)
    • ID=Mxxx 和 Type=milk
    • ID=Infxxx

下面是Have 和所需的输出。

data have;
     input ID $ Type $ Drug $;
     cards;
M001    blood A
M001    blood A
M001    blood A
M001    blood B
M001    blood B
M001    milk  B
M001    blood C
M001    blood C
M002    blood A
M002    blood A
Inf002  blood A
M002    blood A
M002    blood B
M002    milk  C
Inf003  blood B
M003    blood B
;
run;
data want;
     input ID $ Type $ Drug $;
     cards;
M001    milk   B
Inf002  blood  A
M002    blood  A
M002    milk   C
Inf003  blood  B
M003    blood  B
;
run;

例如,inf002 药物 A 观察下的 M002(血液,药物 A)会保留,因为它出现在同一药物组中的婴儿样本之后。但是它上面的两个 M002(血液,A)观察值应该被删除,因为它们发生在同一药物组中的第一个婴儿样本之前。反之,M001(牛奶,B)后面的两个M001(血液,C)观察值应删除,因为药物组不同。

【问题讨论】:

  • 如果母血位于两个母乳之间,或者母乳和婴儿血之间,或者两个婴儿血之间怎么办?
  • 您的结果与您的描述不符。为什么不保留第一个观察结果?您的意思是要删除在母亲的第一个 MILK 记录之前出现的所有 BLOOD 记录?
  • @Bill Huang,如果母血样本介于这两个样本中的任何一个之间,并且与牛奶或婴儿血液来自同一药物组,则将保留该样本。否则,如果我们有来自药物 B 的母血,例如,夹在 A 组的婴儿和 C 组的牛奶之间,它就会被删除。另一方面,如果我们有来自 A 的母血,然后是来自 A 的婴儿血,然后是来自 A 的母血,最后的母血将被保留,但第一个被删除。
  • 以下是我目前对你的逻辑和数据的理解: 对于每组(001002等,包括母婴),(1)每组最多有1条婴儿记录(2)删除直到出现infantmother milk 记录之前的所有内容 (3) 删除每个mother blood 记录,除了紧跟在mother-milkinfant 之后的记录。那是对的吗? Drug 是如何工作的?
  • 此外,如果mother milkinfant 从未出现在群组中怎么办?是否应该删除该组中的所有记录?

标签: if-statement sas grouping


【解决方案1】:

编辑:按(gpDrug)分组。

按键

  1. 使用SAS regex(此处为prxmatch(patt, var))提取ID分组号(代码中的gp)。

  2. 可以逐行检查保持条件,同时也可以按(gpDrug)分组。 gp 的更改由 FIRST.drug 标识。

    • 在使用BY 语句之前,必须对数据集进行排序。由于 SAS 排序是稳定的,所以不会破坏原来的排序。
    • 可以通过在正则表达式解析阶段记录_n_来跟踪原始排序。

代码

* "have" is in your post;
data tmp;
    set have;
    pos = prxmatch('(\d{3})', ID);
    gp = substr(ID, pos, pos+2);  * group number;
    mi = substr(ID, 1, 1);  * mother or infant;
    n = _n_; * keep track of the original ordering;
    drop pos;
run;

proc sort data=tmp out=tmp;
    by gp drug;
run;

data want(drop=flag_keep gp mi);
    set tmp;
    by gp drug;
    * state variables;
    retain flag_keep 0;
    if FIRST.drug then flag_keep = 0;
    * mark keep;
    if (flag_keep = 1) or (mi = "I") or ((mi = "M") and (Type = "milk"))
        then flag_keep = 1;
    if flag_keep = 1 then output;
run;

proc sort data=want out=want;
    by n;
run;

结果:为清楚起见,显示了原始行号 n

   ID      Type   Drug  n
1  M001    milk   B     6    
2  Inf002  blood  A     11    
3  M002    blood  A     12    
4  M002    milk   C     14    
5  Inf003  blood  B     15    
6  M003    blood  B     16

【讨论】:

  • 非常感谢您的帮助!这适用于我在混合中添加更多观察的情况(请参阅对我原始帖子的编辑)。很抱歉,我应该首先澄清,但我基本上想删除在同一血型的第一个牛奶或婴儿血液样本之前发生的药物组内的所有母血观察。因此,在已编辑的数据集中,2 个 M001(血液,C)观察值应该被删除,即使它们发生在同一参与者的牛奶样本(药物 B)之后,因为药物不同。
  • 意思是说“在同一*药物的第一个牛奶或婴儿血液样本之前发生的药物组中,而不是血型
  • 非常感谢您对此的帮助,非常感谢!它现在完美运行。我还接受了您提出的修改,以使我的原始帖子更加清晰和中肯,谢谢!
猜你喜欢
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
  • 2022-08-31
相关资源
最近更新 更多