前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SAS-生物等效性PK分析程序合集

SAS-生物等效性PK分析程序合集

作者头像
Setup
发布2021-04-20 10:53:59
5.5K0
发布2021-04-20 10:53:59
举报

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍近期小编整理了一下生物等效性(BE)试验中PK分析部分的常规处理程序。于是就来分享一下这部分Winnonlin上的操作以及对应的利用SAS实现的程序。

BQL处理

在拿到样本检测数据后(浓度数据通常以Excel外部数据形式进行传输),将外部数据转化成SAS数据集,同时会对浓度数据中低于定量下限的BQL数据进行处理,根据方案中指定的规则进行BQL数据的替换,通常处理规则如下图。

BQL处理规则(摘自某方案)

上面截图为最常规的填补方式,也不乏有其他的花式填补。本文以最常规的填补方式为例。

winnonlin中的操作

在winnonlin中,选择数据选择>send to>Data Management>BQL。

选择BQL

在Main中设置SORT(受试者、周期/采血)、Time(采血时间点)、Concentration(浓度)、Carry(保留需要的变量)。

设置Main

设置填补规则,下图所示,设置Tmax前填补0,Tmax后填补ND。如果BQL无差别替换的话,将下图中的几个ND都替换成0即可。

设置替换规则

SAS中的代码

在SAS中,BQL的替换也是很简单的,下面来看看代码。

代码语言:javascript
复制
/****************************************************************************************************************************************
宏名称    : BQL

目的      : BQL填补

参数说明    :
      inds      输入数据集
      outds     输出数据集
      con       浓度变量
      time      时间变量(时间点,数值型)  
      treat      序列(T / R)
      subjid      受试者编号
      Keyword   关键词
      bql1       填补方式1生成的变量
      bql2       填补方式2生成的变量

      YN        针对Tmax 之后出现的BQL
            0:不考虑Tmax之后的连续BQL(统一按照缺失或者0处理)
            1:考虑Tmax之后出现的连续BQL(连续出现的BQL之后的可测量结果填补ND,自身也ND)
      Tmaxafter   限制Tmax之后出现的BQL
      


填补规则    : 
第一种填补:将BQL全部替换成0
第二种填补:将Tmax之前的BQL替换成0,Tmax之后的BQL替换成ND


%bql(inds=adpc,outds=final,subjid=RANDNUM,
    treat=TRTAL,con=AVAL,time=APCTIM,Keyword=BQL,bql1=BQL01,bql2=BQL02,YN=0);


________________________________________________________________________________________________________________________

__________________________________________________________________________________________________________________________
版本     日期           修改人             修改描述
---     -----------    ------------     ----------------------------------------------------------------------------------
1.0     2021.04.06      Setup           创建
****************************************************************************************************************************************/

%macro  bql(inds=,outds=,subjid=,treat=,con=,time=,Keyword=BQL,bql1=AVAL01,bql2=AVAL02,YN=0,Tmaxafter=1);
data _temp_01;
  set &inds.;
  _temp_con=input(&con.,??best.);
run;

*计算Tmax时间点;
proc sql ;
  create table _temp_02(where=(Cmax=_temp_con)) as
  select distinct &subjid.,&treat.,&time.,_temp_con,max(_temp_con) as Cmax
  from _temp_01   as a
  group by &subjid.,&treat.;
  create table _temp_03 as
  select distinct a.*,Cmax,b.&time. as Tmax label="Tmax"
  from  _temp_01  as a
  left join  _temp_02  as b
  on a.&subjid. =b.&subjid. 
  and a.&treat. =b.&treat. ;
quit;

proc sort data=_temp_03  out=_temp_03  sortseq=linguistic(numeric_collation=on);by &subjid. &treat. &time.  ;quit;
data _temp_04;
  set _temp_03;
  by &subjid. &treat. &time. ;
  retain missfl 0;
  if first.&treat. then do;
    *限制Tmax之后出现的连续的BQL;
     if missing(_temp_con)   %if &Tmaxafter. eq 1 %then %do;and &time.<=Tmax %end ; then missfl=0;
  end;
  else do;
     if missing(_temp_con)   %if &Tmaxafter. eq 1 %then %do;and &time.>Tmax %end ; then missfl=missfl+1; 

     %if &Tmaxafter. eq 1 %then %do;
     else   if missing(_temp_con)  and &time.<=Tmax then missfl=0;
     %end ;
     else if ^missing(_temp_con) and missfl>=2   %if &Tmaxafter. eq 1 %then %do;and &time.>Tmax  %end ; then missfl=missfl+1; 
     else  if ^missing(_temp_con) and missfl<2   %if &Tmaxafter. eq 1 %then %do;and &time.>Tmax  %end ; then missfl=0; 
  end;
run;
proc sort data=_temp_04  out=_temp_04  sortseq=linguistic(numeric_collation=on);by &subjid. &treat. descending &time.  ;quit;
data _temp_04;
  set _temp_04;
  by &subjid. &treat. descending &time.;
  missfllag1=lag(missfl);
  if first.&treat. then call missing(missfllag1);
run;
proc sort data=_temp_04  out=_temp_05  sortseq=linguistic(numeric_collation=on);by &subjid. &treat.  &time.  ;quit;


data &outds.;
  set _temp_05;
  /*第一种填补方式:将所有的BQL当做0处理*/
  &bql1.=&con.;
  if  index(upcase(&con.),"&Keyword.") then &bql1.="0"; 
  /*考虑Tmax后连续2条BQL的情况--连续的俩条BQL之后的数据填补ND*/
  %if &YN. eq 1 %then %do;
  if missfl>=2 or (missfl=1 and missfllag1=2) then &bql1.="ND";
  %end;
  /*将Tmax之前的BQL替换成0,Tmax之后的BQL替换成ND*/
  &bql2.=&con.;
  if  index(upcase(&con.),"&Keyword.") and &time.<Tmax  then &bql2.="0";
  else  if  index(upcase(&con.),"&Keyword.") and &time.>Tmax  then &bql2.="ND";
  %if &YN. eq 1 %then %do;
  if missfl>=2 or (missfl=1 and missfllag1=2) then &bql2.="ND";
  %end;
  drop Cmax Tmax _temp_con missfllag1 missfl;
run;
proc delete data=work._temp_01 _temp_02 _temp_03 _temp_04 _temp_05 ;quit;
%mend;

在BQL填补完成后,就可以在winnonlin中进行PK参数的计算,这里小编就不截图演示了,PK参数的计算小编也没有用SAS实现过,在winnonlin中点点点就可以了。

多因素方差分析

在生物等效性评价中,通常会对Cmax、AUClast、AUCinf_obs进行对数转化后,进行多因素方差分析。

方差分析样表

winnonlin中的操作

如下图,在计算出PK参数后,按照下图所示的点选,然后选择对应的的变量,就能方差分析、单向双侧T检验、置信区间都计算出来,关于Tmax非参数检验将下图所选的改成Crossover即可。这里就不展示winnonlin中具体的操作。

选择Bioequivalence

SAS中的代码

在生物等效性分析中,一般采用Proc Mixed过程对数据进行分析。此处以常规的两制剂、单次给药、双周期、双交叉试验为例。下面以Cmax为例进行计算。

代码语言:javascript
复制
data _rungrpds;
  set adam.adpp;
  if besfl="是"  and UPCASE(param)="CMAX".;
  _temp_aval=Log(aval);
run;
%let subject=RANDNUM;*受试者变量;
%let trtseq=trtseq;*给药顺序;
%let period=period;*周期;
%let trtal=trtal;*制剂;

ods exclude all;
ods output type3=_temp_01;
proc mixed data=_rungrpds method=type3;
    class &subject. &trtseq. &period. &trtal.; 
  model _temp_aval=&trtseq.  &period. &trtal.  ;
     random &subject.(&trtseq.);
  Lsmeans &trtal.;
run;
ods exclude none;
data _final;
  length _param _top $200.;
  set _temp_01;
  _param="ln(Cmax)";
  if upcase(Source)=upcase("&TRTSEQ.") then do _top="序列";SEQ=1;end;
  else if  index(Source,')') then do  _top="受试者(序列)";SEQ=2;end;
  else if upcase(Source)=upcase("&TRTAL.")    then do _top="制剂";SEQ=3;end;
  else if  upcase(Source)=upcase("&PERIOD.")  then do _top="周期";SEQ=4;end;
  else do ; _top="误差";SEQ=5;end;
  label _top="试验因素" _param="药代动力参数" ;
  keep _top   _param DF SS MS FValue ProbF SEQ ;
run; 
proc sort data=_final out= _final  sortseq=linguistic(numeric_collation=on);by  SEQ;quit;

如上代码,即可实现Cmax相关的多因素方差分析。

输出结果(试验数据不展示了)

双向单侧T检验

下面来看一下第二个常规表格,双向单侧T检验,如下图所示。

双向单侧T检验样表

双向单侧T检验分析的实现也是较为简单的,采用PROC MIXED计算出参数,然后利用公式进行计算。采用此公式计算出来的结果与winnonlin结果数值是一致的(T2的正负除外)。

参考另外一篇文献,将T2公式稍改一下,即可得出与winnonlin一致的结果。

SAS中的代码

代码语言:javascript
复制
data _rungrpds;
  set adam.adpp;
  if besfl="是"  and UPCASE(param)="CMAX".;
  _temp_aval=Log(aval);
run;
%let subject=RANDNUM;*受试者变量;
%let trtseq=trtseq;*给药顺序;
%let period=period;*周期;
%let trtal=trtal;*制剂;


ods exclude all;
proc mixed data=_rungrpds;
    class &subject. &trtseq. &period. &trtal.; 
    model _temp_aval=&trtseq. &period. &trtal. &subject.*&trtseq.  /s   ddfm=satterth ;
    random intercept/subject=&subject. ;
    lsmeans &trtal./diff=control('R') alpha=0.1 cl;
    ods output diffs=_temp_diffs lsmeans=_temp_Lsmeans;
run;
ods exclude none;
proc sql UNDO_POLICY=NONE;
  create table _temp_01 as
  select distinct a.*,b.Estimate as Tmean,c.Estimate as Rmean
  from  _temp_diffs  as a
  left join _temp_Lsmeans(where=(&trtal.='T'))   as b on 1=1
  left join _temp_Lsmeans(where=(&trtal.='R'))   as c on 1=1
    ;
quit;

data _temp_01;
  set _temp_01;
  /*Tost 值计算*/
  t1_Tost=(input(Tmean,??best.)-input(Rmean,??best.)-log(0.80))/StdErr;
  t1_TostP =1-probt(abs(t1_Tost),DF);
/*t2_Tost=(log(1.25)-(input(Tmean,??best.)-input(Rmean,??best.)))/StdErr;*书上公式,但算出来符号与winNonlin不一致;*/
  t2_Tost=((input(Tmean,??best.)-input(Rmean,??best.))-log(1.25))/StdErr;
  t2_TostP =1-probt(abs(t2_Tost),DF);
run;

置信区间法

常规表格三,生物等效性中的置信区间的计算,如下图所示。

置信区间样表

这部分的计算依然采用的是PROC MIXED过程步。这个表也是主要评价是否等效的一个关键表,下面来看一看这个表实现的过程。

SAS中的代码

代码语言:javascript
复制


data _rungrpds;
  set adam.adpp;
  if besfl="是"  and UPCASE(param)="CMAX";
  _temp_aval=Log(aval);
run;
%let subject=RANDNUM;*受试者变量;
%let trtseq=trtseq;*给药顺序;
%let period=period;*周期;
%let trtal=trtal;*制剂;

ods exclude all;
proc mixed data=_rungrpds;
    class &subject. &trtseq. &period. &trtal.; 
    model _temp_aval=&trtseq. &period. &trtal. ;
     random &subject.(&trtseq.);
    lsmeans &trtal./diff=control('R') alpha=0.1 cl;
    ods output covparms=_temp_Covparms tests3=_temp_type diffs=_temp_diffs lsmeans=_temp_Lsmeans;
run;
ods exclude none;

/*T/R 几何均值*/
data _temp_01;
  set _temp_Lsmeans;
  Geomean=compress(put(round(exp(Estimate),0.001),12.3));
  Mean=Estimate;
  keep &trtal. Geomean Mean ;
run;
proc transpose data=_temp_01 out=_temp_01 prefix=AVAL;
by  &trtal.;
var  Geomean Mean;
run;

data _temp_01;
  set _temp_01;
  _nname_=strip(&trtal.)||strip(_NAME_);
run;

proc transpose data=_temp_01 out=_temp_01(drop=_name_) ;
  var AVAL1;
  id  _nname_;
run;

/*T/R 例数*/
proc sql;
  create table _temp_02 as
  select distinct &trtal.,cats(count(distinct &subject. )) as n
  from _rungrpds
  group by &trtal.
  order by &trtal. desc;
quit;
proc transpose data=_temp_02 out=_temp_02(drop=_name_) prefix=N;
  var n;
  id &trtal.;
run;

data _temp_03;
  set _temp_diffs;
  ratio=exp(Estimate);
  Estimate2=exp(Estimate)*100;
  Lower1=exp(Lower);
  Upper1=exp(Upper);
  keep Estimate2  ratio Lower1 Upper1  ;
run;

data _temp_Covparms;
  set _temp_Covparms;
  AVAL=sqrt(exp(Estimate)-1);
  if CovParm="Residual" then do;n_name_="CV01";n_label_="个体内变异";end;
  else do;n_name_="CV02";n_label_="个体间变异";end;
run;
proc transpose data=_temp_Covparms out=_temp_04 ;
  var AVAL;
  id n_name_ ;
  idlabel n_label_ ;
run;

proc sql noprint;
  select count(distinct &subject.) into :count trimmed from _rungrpds;
  select ratio into :ratio trimmed from _temp_03;
  select CV01 into :cv trimmed from _temp_04;
quit;
ods output output=_temp_05;
proc power;
  twosamplemeans test=equiv_ratio 
    alpha = 0.05 
    lower = 0.8
    upper = 1.25 
    meanratio = &ratio. 
    cv = &cv.
    npergroup =&count.
    power =.;
run;
ods exclude none;

data _final;
  merge _temp_01-_temp_05;
run;

非参数检验

针对Tmax的分析,通常是采用配对非参数的方法进行差异性检验(指导原则)。winnonlin上的crossover出来的结果应该不是采用这个方法做的,本来试着去还原一下winnonlin的方法,但是尝试几次,始终结果不一致,就放弃。

指导原则上的要求

SAS中的代码

代码语言:javascript
复制
%let subject=RANDNUM;*受试者变量;
%let trtseq=trtseq;*给药顺序;
%let period=period;*周期;
%let trtal=trtal;*制剂;


data _rungrpds;
  set adam.adpp;
  if besfl="是"  and UPCASE(param)="TMAX";
run;
proc sort data=_rungrpds  out=_rungrpds ;by &subject.  ;;quit;
proc transpose data=_rungrpds out=Temp01 ;
by   &subject. ;
var AVAL;
id &trtal. ;
run;
data Temp01;
  set Temp01;
  DIF=R-T;
run;
ods exclude none;
ODS TRACE ON;
ODS output TestsForLocation=temp2;
proc univariate DATA=Temp01;
  var DIF;
run;
ODS TRACE OFF;
ods exclude all;

总结

上面就是生物等效性分析中的常规表格,还有几张常规表格,基本就类似于清单一样直接输出,当然还有几张图,譬如药时曲线等,作图可见小编历史推文SAS-时药曲线的绘制SAS-时药曲线的绘制(完)SAS-临床试验程序绘图合集(一),也都是很简单的操作。另外小编这里也开通一项功能,承接临床试验数据分析(包括但不限于PK参数计算及分析等)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SAS程序分享号号号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档