上班 上班 上班 上班 上班 上班 上班 上班 上班
1. LOCF 或者 像LOCF
LOCF全称是Last Observation Carries Forward,简单说是一种缺失值的填补方法,用前一个非空的记录值去填补后一个空值。看图👇
假设场景:在固定的时间内需要受试者重复测量一项检查,比如收缩压, 如果测量了,就会有值,因为各种原因未测量或者未记录,就为缺失值。按LOCF填补缺失值,对于同一个受试者如果前一次测量有值,则当前缺失值就填补为前一次测量值,如果首次为空值,则不进行填补。最终就会得到上面的结果。
这里参考 code 用 retain 实现需求,也可以用其他方法。
proc sort data=raw_data;
by subject id;
run;
data locf;
set raw_data;
by subject id;
value_=value; * in case replace raw value;
retain new;
if first.subject and value_=. then new=.;
else if first.id and value_^=. then new=value_;
else if first.id and value_=. then value_=new;
run;
2. Note: The query requires remerging summary statistics back with the original data.
使用sql语句进行分组计数,有时sas log会得到这样的note,原因是select语句中的变量用到了分组外的变量,最常见是使用了 * 。
如下示例,当想要获得一个班不同性别的同学年龄的差异,且保留原始班级同学的信息,使用sql就得出,班上女生有5个不同的年龄,男生有6个。此时,分组信息时sex,但select语句出现了*,也就是出现了除sex以外的变量,就会出现note提示。
proc sql;
select *,count(distinct age) as n_age from sashelp.class
group by sex;
quit;
清除Note可以用join语句改写,得到一样的结果。
proc sql;
select a.*,b.n_age from sashelp.class a left join
(select sex,count(distinct age) as n_age from sashelp.class
group by sex) b
on a.sex=b.sex;
quit;
3. 重新认识 libname
最早接触libname ,还是在初次学习sas,始终停留在form1最简单的形式 LIBNAME libref 'SAS-library' 。再后来工作逻辑库都在 init.sas 定义好了,已经很久没用了哈哈哈哈。
form1是分配指定路径为逻辑库
form2是解除逻辑库的关联
form3是将指定逻辑库的信息写在SAS log上
form4是将多个逻辑库关联到一个逻辑库
这里form4指定的多个逻辑库必须提前设置过;也可以是逻辑库和外部文件的结合,下面是官方的例子。
libname v6 'v6–SAS-library';
libname v9 'v9–SAS-library';
libname allmine (v9 v6);
libname allmine (v9 v6 'some-filename');
libname allmine ('file-1' 'file-2' 'file-3');
还有一些可能会用到的libname-options都能了解到,如 access=readonly
4. Functions: index vs indexc
INDEX(source, excerpt): 在字符串中搜索字符表达式,并返回字符串第一次出现时字符串第一个字符的位置。
INDEXC(source, excerpt-1 <, …excerpt-n>): 在字符表达式中搜索任何指定字符,并返回该字符的位置。
可以看出index是将搜索字符作为整体,而indexc是将搜索字符中出现的任意字符。
data test;
string = "ABCDEFG11GFE";
in1 = index(string,"GFE");
in2 = indexc(string,"GFE");
run;
in1, index返回的是GFE作为一个整体首次出现的位置,即整体中第一个字母出现的位置为11;
in2 , indexc返回的是GFE三个字符“G" "F" "E"任意一个字符首次出现的位置,先出现的"E"位置为5.
5. Function: verify
VERIFY(source, excerpt-1 <, ...excerpt-n>) : 返回不在指定数据字符串中的字符串中第一个字符的位置。可以理解为去检查字符串是否包含不需要的值。
实际应用中,可以去看一个变量是否包含了误填的信息。比如,一项问题的回答有“ABCD”四个答案,但得到的结果含有了数字或其他,就可以用这个函数。
data verif;
input id $ 1-3
value $ 5-8;
v = verify(value,"ABCD ");
ok = v eq 0;
datalines;
001 ABCC
002 AXBC
003 BB1D
004 ABC
;
run;
可以看出,002和003都有书写错误,verify返回值不为0。当然这种场景通常在DM edit check就会排查出来。另外,建议verify后指定的字符填上空值,如果不给空值,value长度不合适,会返回首次空值的位置。