Work Tips: SAS Clinical programming -3

sp的工作都是这样吗?忙的时候很忙,闲的时候很闲。

1. Functions: tranwrd & transtrn

TRANWRD(sourcetargetreplacement):替代目标字符串中的指定字符。

TRANSTRN(sourcetargetreplacement): 替代或者移除目标字符串中的指定字符。

这在知道替换词或者替换符号的时候很好用,并且两个作用相同。唯一不同的是对于指定word长度为0时,tranwrd会替换为空白字符,transtrn会替换为空。

data holiday;
    set sashelp.holiday;
    /****Replace all occurence of "_" with "" ****/
    category1a=tranwrd(category,"_",trimn(""));
    category1b=transtrn(category,"_",trimn(""));
    /****Replace all occurence of "_" with "-" ****/
    category2a=tranwrd(category,"_","-");
    category2b=transtrn(category,"_","-");
    /****Replace all occurence of "US" with "United States" ****/
    category3a=tranwrd(category,"US","United States");
    category3b=transtrn(category,"US","United States");
run;

2. Functions: whichc & whichn

WHICHC(stringvalue-1 <, value-2, ...>): 在给定字符串value-n中搜索string并返回对应的索引值。

WHICHN(argumentvalue-1 <, value-2, ...>):在给定数值value-n中搜索值并返回对应的索引值。

可以根据已知的分类直接赋值,类似作用的写法或函数有很多。

data class;
    set sashelp.class;
    sexn = whichc(sex,"F","M");
run;

 

但是需要注意的是,返回的都是索引值,索引值都是从1开始,所以最低的赋值为1,如果找不到对应的值则为0。这个在给arm或者treatment分组的时候很合适,不需要多个if-else statement。但是如果value太多,还是做成format的形式更便捷。

/********Create dummy treatment dataset********/
data dummy_trt;
    do subject = 1 to 5;
        trt = cats("P1CH",subject);
        output;
    end;
run;

/********assign number of treatment group********/
data dummy_trtn;
    set dummy_trt;
    array treatment(4) $8 _temporary_ ("P1CH1","P1CH2","P1CH3","P1CH4");
    trtn = whichc(trt, of treatment[*]);
/*  trtn = whichc(trt,"P1CH1","P1CH2","P1CH3","P1CH4"); */
run;

3. 建议code起始都加一句

proc dataset lib=work  memtype=data kill nolist; quit;

 这样做的好处是在最后multirun时,不会因为别人程序生成的数据集影响到自己的程序,即先清空work环境下所有的临时数据集。

4. ifc & ifn 让code变得简洁

IFC/IFN (logical-expressionvalue-returned-when-truevalue-returned-when-false
<, value-returned-when-missing>)

两个用法的区别是return的是字符串还是数值,使用起来很简洁。

age_group = ifc(age^=. and age>60,"> 60 years","<= 60 years");

5. ifc & ifn 遇上zero or missing numeric variable

Safety output会经常要计算各个分类变量的受试者患者数n,以及在人群N中的占比,并以 n(%) 来展示结果。当人群N为各个treatment group时,会遇到某一个或几个组还没有患者enroll,此时N就为0,而分母在除法中是不能为0的。

data aaa;
    a=2; b=3; output;
    a=5; b=0; output;
    a=0; b=0; output;
    a=.; b=5; output;
run;

/***original code: calculate percentage c ***/
data bbb;
    set aaa;
    length c 8.;
    c = ifn(b>0, a/b*100, .);
run;

a) clean note: Division by zero detected

按IFN的逻辑,最开始的代码没有毛病,只有当分母b大于0的时候,才会进行除法运算,我没查到出现zero detected的原理是什么,但是clean note比较容易,只要改为用函数运算就好。

但是依旧会报missing value的note。

/***clean note: Division by zero detected ***/
data bbb;
    set aaa;
    length c 8.;
    c = ifn(b>0 and a^=. , divide(a/b)*100, .);
run;

b) clean note: Missing values

即使第一个参数的逻辑条件绕过缺失值,只要后面true或false涉及数值运算,这条note就会始终出现。虽然不影响output的结果,但是这种note也是不允许出现的。

这种情况 IFC/IFN 就不再适用,而是要换回传统的 if-else statement。

/***clean note: Missing values ***/
data bbb;
    set aaa;
    length c 8.;
    if b>0 and a^=. then c = divide(a/b)*100 ;
    else c = .;
run;

 虽然清空了sas log, 但为什么出现这些问题,至今我没还没有找到答案,或许哪位民间高人可以指点一下?

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值