Parallel design [unequal variances] in Phoenix/WinNonlin [Software]

posted by Helmut Homepage – Vienna, Austria, 2013-07-04 22:22 (4370 d 18:06 ago) – Posting: # 10938
Views: 14,678

Dear all,

some veterans might remember this thread from 2007 (!) where I showed that WinNonlin assumes equal variances in parallel designs.
This week Linda Hughes of Pharsight posted a coding at the Extranet which works both in Phoenix and ‘classical’ WinNonlin (I tested PHX 6.3 and WNL 5.3). Her solution follows a hint given at SAS’ knowledge base. Of course, our SAS-guru Detlew knew that already. ;-)

Here is my setup in [image] (AFAIK the same one is coded in bear). First the original balanced data set with similar variances (T 0.1796, R 0.1292) and then a modified imbalanced data set with unequal variances (T 0.5639, R 0.1292).

disply <- function(table) {
    cat("\nTest/Reference with 95% Confidence Limits (90% CI)", fill=T)
    round(table, 2) }

# original data
PK <- ("
  AUC, treatment
  44.1, R
  33.6, R
  45.5, R
  35.3, R
  26.0, R
  38.2, R
  25.6, R
  58.0, R
  47.2, R
  17.5, R
  51.7, R
  24.5, R
  19.5, T
  67.2, T
  25.7, T
  33.6, T
  25.1, T
  44.1, T
  16.5, T
  47.3, T
  22.6, T
  36.3, T
  29.4, T
  18.3, T")
txtcon <- textConnection(PK)
PKdata <- read.table(txtcon, header=T, sep=",", strip.white=T)
close(txtcon)
PKdata$logAUC <- log(PKdata$AUC)
attach(PKdata)
relevel(treatment, ref = "R")
t1 <- t.test(logAUC ~ treatment, data=PKdata, var.equal=T, conf.level=0.90)
tbl1 <- matrix(
    c(as.numeric(100*exp(diff(t1$estimate))), sort(as.numeric(100*exp(-t1$conf.int)))),
    byrow=T, nrow=1)
dimnames(tbl1) <- list("t-test (equ. var.) ", c("Point Estimate", "Lower CL", "Upper CL"))
t2 <- t.test(logAUC ~ treatment, data=PKdata, var.equal=F, conf.level=0.90)
tbl2 <- matrix(
    c(as.numeric(100*exp(diff(t2$estimate))), sort(as.numeric(100*exp(-t2$conf.int)))),
    byrow=T, nrow=1)
dimnames(tbl2) <- list("Welch-Satterthwaite", c("Point Estimate", "Lower CL", "Upper CL"))
disply(tbl1)
disply(tbl2)

# modified data
PK <- ("
  AUC, treatment
  44.1, R
  33.6, R
  45.5, R
  35.3, R
  26.0, R
  38.2, R
  25.6, R
  58.0, R
  47.2, R
  17.5, R
  51.7, R
  24.5, R
  58.5, T
  201.6, T
  77.1, T
  33.6, T
  25.1, T
  44.1, T
  16.5, T
  47.3, T
  22.6, T")
txtcon <- textConnection(PK)
PKdata <- read.table(txtcon, header=T, sep=",", strip.white=T)
close(txtcon)
PKdata$logAUC <- log(PKdata$AUC)
attach(PKdata)
relevel(treatment, ref = "R")
t3 <- t.test(logAUC ~ treatment, data=PKdata, var.equal=T, conf.level=0.90)
tbl3 <- matrix(
    c(as.numeric(100*exp(diff(t3$estimate))), sort(as.numeric(100*exp(-t3$conf.int)))),
    byrow=T, nrow=1)
dimnames(tbl3) <- list("t-test (equ. var.) ", c("Point Estimate", "Lower CL", "Upper CL"))
t4 <- t.test(logAUC ~ treatment, data=PKdata, var.equal=F, conf.level=0.90)
tbl4 <- matrix(
    c(as.numeric(100*exp(diff(t4$estimate))), sort(as.numeric(100*exp(-t4$conf.int)))),
    byrow=T, nrow=1)
dimnames(tbl4) <- list("Welch-Satterthwaite", c("Point Estimate", "Lower CL", "Upper CL"))
disply(tbl3)
disply(tbl4)


In Phoenix you need a Subject variable and a dummy, which contains 1 in all cells. For simplicity I named it Period.
In the default coding you have only one Fixed Effect, namely Treatment. Now for the trick:
In the Setup map additionally Subject and Period to Classification.
Fixed: Treatment
Variance Structure > Repeated:
Repeated Specification: Period
(:surprised:)
Variance Blocking Variable (Subject): Subject
Group: Treatment


Now let’s see.
                                             PE       90% CI     CVtot. CV(R) CV(T)
orig. data set R 3.0.1     var.equal=TRUE   83.66  63.51 110.19
                           var-equal=FALSE  83.66  63.49 110.22
               Phoenix 6.3 standard coding  83.66  63.51 110.19  40.86
                           modified coding  83.66  63.49 110.22  40.86  37.14 44.35
mod. data set  R 3.0.1     var.equal=TRUE  124.35  81.21 190.41
                           var-equal=FALSE 124.35  76.36 202.51
               Phoenix 6.3 standard coding 124.35  81.21 190.41  60.54
                           modified coding 124.35  76.36 202.51  60.54  37.14 87.04

As a side effect Phoenix spits out the treatments’ total variances in Var(Period*Treatment*Subject)_11 (R) and Var(Period*Treatment*Subject)_12 (T). In the balanced case the mean of these variances equals the total (pooled) total variance of the standard set-up. Have to figure out yet how to weight them properly in the imbalanced case.*

In the next release of Phoenix (~1st half 2014), the dummy variable will not be needed any more (i.e., can be left empty).

<div lang="de" xml:lang="de">

Was lange währt, wird endlich gut.

</div>




Dif-tor heh smusma 🖖🏼 Довге життя Україна! [image]
Helmut Schütz
[image]

The quality of responses received is directly proportional to the quality of the question asked. 🚮
Science Quotes

Complete thread:

UA Flag
Activity
 Admin contact
23,424 posts in 4,927 threads, 1,673 registered users;
43 visitors (0 registered, 43 guests [including 11 identified bots]).
Forum time: 16:28 CEST (Europe/Vienna)

Medical researches can be divided into two sorts:
those who think that meta is better and those
who believe that pooling is fooling.    Stephen Senn

The Bioequivalence and Bioavailability Forum is hosted by
BEBAC Ing. Helmut Schütz
HTML5