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-如何找出数据集超长变量及观测,并自动进行变量的拆分...
程序下载
上面的部分程序也可到小编网站上进行下载,如下图路径。
工具推荐列表
- Windows下程序启动时出现0xc000007b错误的解决方案
- 外媒报道:CBM.com、NMA.com等域名齐交易
- ObjectDataSource与GridView配合使用经验总结系列一:数据绑定
- ObjectDataSource与GridView配合使用经验总结系列二:分页
- 网页优化系列二:使用Cache缓存静态文件、图片(asp.net版)
- Linux用户与“最小权限”原则
- WPF一步一脚印系列(1):万事起头难
- 自定义迭代器使用foreach
- 理解cookie的path和domain属性
- 静态页面设置缓存、动态页面设缓存(不断更新中。。。。)
- 区块链技术如何把你的游戏资产真正变为你的资产
- Python标准库07 信号 (signal包,部分os包)
- 当css属性width设为100%时
- GridView实战一:自定义分页、排序、修改、插入、删除
- 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 数组属性和方法
- Python | 面试的常客,经典的生产消费者模式
- LeetCode 87,因为题目晦涩而被点了1500+反对的搜索问题
- LeetCode 87,远看是字符串其实是搜索,你能做出来吗?
- Golang中的interface是干嘛的?从面向对象中的多态与接口开始说起……
- pandas | DataFrame基础运算以及空值填充
- C++设计模式笔记(08) - Factory Method工厂方法
- 【Code】GraphSAGE 源码解析
- Kafka常见的导致重复消费原因和解决方案
- 近30个MySQL常用函数,必须推荐!
- 搞定 CompletableFuture,并发异步编程和编写串行程序还有什么区别?你们要的多图长文
- 用注解实现 MyBatis 开发
- MyBatis 实现数据的增删改查
- 0790-5.16.2-NameNode服务的edits不同步异常
- 0789-不停止MySQL服务重做备库的方法
- 防盗链Apache和Nginx配置对比