SAS-新规试行下诞生的程序
昨日,《药物临床试验数据递交指导原则》(试行)版正式公布了,在小编阅读后,于是本文因时而生了。
变量长度要求
在满足V5格式XPT变量长度的同时,需要字符变量长度是整个项目中相同变量名真实长度的最大值。本文将分享一段SAS小程序,自动修改逻辑库下字符变量长度为真实长度的最大值。
options nofmterr compress=yes validvarname=upcase ;
libname test "EData";
*计算 输入数据集的每个变量真实的最大长度;
%macro chk_var_len(inds);
%local libname memname;
%if &inds.= %then %do;
%put NOTE:plesce check your dataset name;
%return;
%end;
%if %length(%sysfunc(compress("&inds.","."))) ne %length(%sysfunc(compress("&inds.",""))) %then %do;
%let libname=%scan("&inds.",1,".");
%let memname=%scan("&inds.",2,".");
%end;
%else %do;
%let libname=WORK;
%let memname=&inds.;
%end;
proc sql noprint;
select strip("MAX(length(")||strip(NAME)||strip("))")||" as "||strip("len_")||strip(NAME) into:varlist separated by "," from sashelp.vcolumn
where libname=upcase("&libname.") and memname=upcase("&memname.") and type='char' ;
quit;
proc sql undo_policy=none;
create table tp1_&memname. as select distinct &varlist. from &inds. ;
quit;
proc transpose data=tp1_&memname. out=tp1_&memname. ;
var _all_;
run;
data tp1_&memname.;
set tp1_&memname.;
length domain var $200.;
domain=upcase("&memname.");
var=substr(_NAME_,5);
drop _NAME_;
run;
%mend;
%macro chklib_var_len(lib=);
*利用循环得到每个数据集 每个变量的最大长度 ;
proc sql noprint;
select count(distinct memname) into: nn from dictionary.columns where libname=upcase("&lib.");
select distinct memname into:mem1-:mem%left(&nn.) from dictionary.columns where libname=upcase("&lib.");
quit;
%do i=1 %to &nn;
%chk_var_len(inds=&lib..&&mem&i.)
%if &i=1 %then %do;
data temp1;
set tp1_&&mem&i.;
run;
%end;
%if &i.>1 %then %do;
data temp1;
set temp1 tp1_&&mem&i.;
run;
%end;
%end;
proc datasets lib=work memtype=data noprint;
delete tp1_:;
run;
quit;
*得到长度存入temp1数据集后;
proc contents data=&lib.._all_ out=_varstemp10(keep=LIBNAME memname NAME LABEL type Varnum length) DIRECTORY NOPRINT MEMTYPE=data CENTILES;
proc sort data=_varstemp10 out=_varstemp10 sortseq=linguistic(numeric_collation=on);by memname Varnum ;
run;
proc sql ;
*计算最大长度;
create table _varstemp11 as
select *,max(COL1) as newlen
from temp1 group by var;
*并入全部变量列表中;
create table _varstemp12 as
select LIBNAME,memname,strip(NAME)||" "||ifc(^missing(newlen),strip("$")||strip(put(newlen,8.))||strip('.'),strip(put(LENGTH,8.))||strip('.')) as final
from _varstemp10 as a
left join _varstemp11 as b
on a.memname =b.domain
and a.NAME =b.var
order by memname,Varnum;
quit;
*修改长度不用报警告;
options varlenchk=nowarn;
data _null_;
set _varstemp12;
length news fmt $20000.;
retain news fmt;
by memname notsorted;
if first.memname then do;news=strip(final);
if index(final,'$') then fmt=strip(final);
else fmt="";
end;
else do news=strip(news)||" "||strip(final);
if index(final,'$') then fmt=strip(fmt)||" "||strip(final);
end;
if last.memname then call execute("data "||memname||"; length "||strip(news)||
"; format "||strip(fmt)||
"; informat "||strip(fmt)||
";set "||strip(LIBNAME)||strip(".")||strip(memname)||strip(";run;"));
run;
proc datasets lib=work memtype=data noprint;
delete _varstemp:;
run;
quit;
%mend;
%chklib_var_len(lib=test);
SAS程序递交
5月份的征求意见稿中,“不包含外部程序调用,尤其应避免大型宏程序的嵌套”已经修改成了“避免外部(宏)程序调用”。所以,从字面意思来看还是可以使用宏程序的,也可以使用嵌套宏程序的,只是宏程序的代码需要放入当前程序内部,不能外部调用。递交程序代码需要txt格式,实现方法很多,小编实现的方法是SAS,喜欢其他方法实现的请忽略。参考小编历史文章(点击下方可跳转)。
数据说明文件
一般我们习惯性的将数据说明文件写在Excel中,现在提出要求需要XML或PDF,从文档中先提到XML 后提到PDF,小编猜测更倾向于XML文件。XML文件大概类似于CDISC标准中的Define.XML。所以SAS程序员可能难以避免的需要研究一下Define.XML的样式。可参考小编历史文章(点击下方可跳转)。
业内的Define的制作大概都是采用P21这个软件来制作,不过目前该软件只支持Define 2.0。如果要做自己Define,最好还是需要了解一下CDISC标准中Define相关的知识及制作的原理。
其他可能用到的
大概还能用到SAS编程的地方也就是变量超过200个字符的拆分和XPT的转化等。XPT的转化程序SAS自带内置宏里面也是有的,不过感觉自带内置宏不太靠谱。建议大家还是使用SAS中xport引擎方式去生成。查看自带内置宏方法可见小编历史推文。
SAS-如何找出数据集超长变量及观测,并自动进行变量的拆分...
程序下载
上面的部分程序也可到小编网站上进行下载,如下图路径。
工具推荐列表
- 串口通信控制器的Verilog HDL实现(三) 发送模块的Verilog HDL 实现
- 串口通信控制器的Verilog HDL实现(二) 波特率发生器模块
- 串口通信控制器的Verilog HDL实现(一) 顶层模块
- 双口同步RAM
- 单口RAM
- Python 基础:类与函数
- 论 Python 装饰器控制函数 Timeout 的正确姿势
- 巧用 SecureCRT 实现复杂的 ssh 登录过程自动化
- pyDes 实现 Python 版的 DES 对称加密/解密
- 流水灯
- Chrome 自动化交互利器:用 tampermonkey 向页面注入自定义 Javascript
- 一次小折腾:PyCharm 调用 Cygwin Python 找不到 time、sys 等内置模块
- 网站数据统计分析之二:前端日志采集是与非
- Linux Shell 从入门到删除根目录跑路指南
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 绘制分组散点图(克里夫兰点图)
- ggplot2绘制玫瑰图
- 绘制极坐标系条形图
- 四步重新认识冗余机器人的控制器设计
- 人脸识别接入常见问题汇总
- TKE上关于postStart 和preStop使用
- 文字识别接入常见问题
- 从 1 到 0 构建博客项目(2) -- 操作系统篇(2)--定制Centos
- 使用Angular依赖注入自定义SAP Spartacus的ProductAdapter
- 获取SAP Spartacus当前显示产品json数据的又一办法
- SAP Spartacus注入自定义的CurrentProductService
- Redis系列(十三)应用之分布式锁
- Oracle数据库 sql条件查询语句与练习
- (六)Hive优化
- mapreduce -- wordcount执行流程