R/mt.func.R

Defines functions mt.niceres mt.number2na mt.na2number mt.getmaxB mt.transformL mt.transformV mt.transformX mt.checkothers mt.checkV mt.checkX mt.checkclasslabel mt.sample.label mt.sample.rawp mt.sample.teststat mt.minP mt.maxT mt.teststat.num.denum mt.teststat

Documented in mt.checkclasslabel mt.checkothers mt.checkV mt.checkX mt.getmaxB mt.maxT mt.minP mt.na2number mt.niceres mt.number2na mt.sample.label mt.sample.rawp mt.sample.teststat mt.teststat mt.teststat.num.denum mt.transformL mt.transformV mt.transformX

.mt.BLIM<-2^30
.mt.naNUM<- -93074815
.mt.RandSeed<-3455660
#the maxim number of setting of the permutation, it's not resettable
#in the current version. the numer comes from the largest
#integer can be 2^32, while we need to exlcude one sign bit, and
#to exclude another bit for safety.


#dyn.load("multtest.so")
#X is a matrix data
#classlabel is a vector
mt.teststat<-function(X,classlabel,test="t",na=.mt.naNUM,nonpara="n")
{
    if(is.factor(classlabel)) classlabel<-unclass(classlabel)-1
    extra<-max(classlabel)+1
    mt.checkothers(na=na,nonpara=nonpara)
    tmp<-mt.transformX(X,classlabel,test,na,nonpara)
    options<-c(test,"abs","y"); #"abs"  and "y" has no meaning here
    res<-.C("get_stat",as.double(tmp$X),as.integer(tmp$m),
               as.integer(tmp$n),as.integer(tmp$classlabel),as.double(na),
               teststat=double(tmp$m),as.character(options),
               as.integer(extra), PACKAGE="multtest")$teststat
    res[abs(res)>=0.9*1e20]<-NA
    res
}
mt.teststat.num.denum<-function(X,classlabel,test="t",na=.mt.naNUM,nonpara="n")
{
    extra<-max(classlabel)+1
    mt.checkothers(na=na,nonpara=nonpara)
    tmp<-mt.transformX(X,classlabel,test,na,nonpara)
    options<-c(test,"abs","y"); #"abs"  and "y" has no meaning here
    teststat<-.C("get_stat_num_denum",as.double(tmp$X),as.integer(tmp$m),
	       as.integer(tmp$n),as.integer(tmp$classlabel),as.double(na),
	       t.num=double(tmp$m),t.denum=double(tmp$m),as.character(options),
               as.integer(extra), PACKAGE="multtest")

    res<-cbind(teststat.num=teststat$t.num,teststat.denum=teststat$t.denum)
    mt.niceres(res,X)
}
  mt.maxT<-function(X,classlabel,test="t",side="abs",
                  fixed.seed.sampling="y",B=10000,na=.mt.naNUM,nonpara="n")
{
    if(is.factor(classlabel)) classlabel<-unclass(classlabel)-1
    extra<-max(classlabel)+1
    mt.checkothers(side=side,fixed.seed.sampling=fixed.seed.sampling,B=B,na=na,nonpara=nonpara)
    tmp<-mt.transformX(X,classlabel,test,na,nonpara)
    newB<-mt.getmaxB(classlabel,test,B)
    if(B==0||newB<B)
      fixed.seed.sampling<-"n" #as we're doing complete premutation
    options<-c(test,side,fixed.seed.sampling);
    res<-.C("get_maxT",as.double(tmp$X),as.integer(tmp$m),
	    as.integer(tmp$n),as.integer(tmp$classlabel),as.double(na),
	    t=double(tmp$m),p=double(tmp$m),adjP=double(tmp$m),
	    as.integer(newB),index=integer(tmp$m),as.character(options),
               as.integer(extra), PACKAGE="multtest")

    res<-cbind(index=res$index,teststat=res$t,rawp=res$p,adjp=res$adjP)
    mt.niceres(res,X,res[,1])
}
mt.minP<-function(X,classlabel,test="t",side="abs",
                  fixed.seed.sampling="y",B=10000,na=.mt.naNUM,nonpara="n")
{
    if(is.factor(classlabel)) classlabel<-unclass(classlabel)-1
    extra<-max(classlabel)+1
    mt.checkothers(side=side,fixed.seed.sampling=fixed.seed.sampling,B=B,na=na,nonpara=nonpara)
    tmp<-mt.transformX(X,classlabel,test,na,nonpara)
    newB<-mt.getmaxB(classlabel,test,B)
    if(B==0||newB<B)
      fixed.seed.sampling<-"n" #as we're doing complete premutation
    options<-c(test,side,fixed.seed.sampling);
    res<-.C("get_minP",as.double(tmp$X),as.integer(tmp$m),
	    as.integer(tmp$n),as.integer(tmp$classlabel),as.double(na),
	    t=double(tmp$m),p=double(tmp$m),adjP=double(tmp$m),
            plower=double(tmp$m),as.integer(newB),index=integer(tmp$m),
            as.character(options),as.integer(extra), PACKAGE="multtest")

    res<-cbind(index=res$index,teststat=res$t,rawp=res$p,adjp=res$adjP,plower=res$plower)
    mt.niceres(res,X,res[,1])
}
mt.sample.teststat<-function(V,classlabel,test="t",fixed.seed.sampling="y",
                       B=10000,na=.mt.naNUM,nonpara="n")
{
  extra<-max(classlabel)+1
  mt.checkothers(fixed.seed.sampling=fixed.seed.sampling,B=B,na=na,nonpara=nonpara)
  tmp<-mt.transformV(V,classlabel,test,na,nonpara)
  newB<-mt.getmaxB(classlabel,test,B)
  if(B==0||newB<B)
    fixed.seed.sampling<-"n" #as we're doing complete premutation
  options<-c(test,"abs",fixed.seed.sampling);#the "abs" has no meaing here.
  res<-t(.C("get_samples_T",as.double(tmp$V),as.integer(tmp$n),
          as.integer(tmp$classlabel),T=double(newB),as.double(na),
          as.integer(newB),as.character(options),as.integer(extra),
            PACKAGE="multtest")$T)
  res[abs(res)>=0.9*1e20]<-NA
  res
}
mt.sample.rawp<-function(V,classlabel,test="t",side="abs",
                       fixed.seed.sampling="y",B=10000,na=.mt.naNUM,nonpara="n")
{
  extra<-max(classlabel)+1
  mt.checkothers(side=side,fixed.seed.sampling=fixed.seed.sampling,B=B,na=na,nonpara=nonpara)
  tmp<-mt.transformV(V,classlabel,test,na,nonpara)
  newB<-mt.getmaxB(classlabel,test,B)
  if(B==0||newB<B)
    fixed.seed.sampling<-"n" #as we're doing complete premutation
  options<-c(test,side,fixed.seed.sampling);
  res<-.C("get_samples_P",as.double(tmp$V),as.integer(tmp$n),
          as.integer(tmp$classlabel), P=double(newB),as.double(na),
          as.integer(newB),
          as.character(options),as.integer(extra), PACKAGE="multtest")$P
  res[abs(res)>=0.9*1e20]<-NA
  res
}
mt.sample.label<-function(classlabel,test="t",
                            fixed.seed.sampling="y",B=10000)
{
  extra<-max(classlabel)+1
  tmp<-mt.transformL(classlabel,test)
  mt.checkothers(fixed.seed.sampling=fixed.seed.sampling,B=B)
  newB<-mt.getmaxB(classlabel,test,B)
  if(B==0||newB<B)
    fixed.seed.sampling<-"n" #as we're doing complete premutation
  options<-c(test,"abs",fixed.seed.sampling); #the "abs" has no meaing here
  res<-.C("get_sample_labels",as.integer(tmp$n),as.integer(tmp$classlabel),
          as.integer(newB), S=integer(tmp$n*newB),as.character(options),
          as.integer(extra), PACKAGE="multtest")$S
  resl<-matrix(res,nrow=tmp$n)
  if(test=="pairt"){
    #restore the original classlabelling
    resn<-matrix(0,nrow=2*tmp$n,ncol=newB)
    for(i in c(1:tmp$n))
      for(j in c(1:newB)){
        if(resl[i,j])
          resn[2*i,j]<-1
        else resn[2*i-1,j]<-1
      }
    resl<-resn
  }
  t(resl)
}
#used for private function
mt.checkclasslabel<-function(classlabel,test)
{
  classlabel<-as.integer(classlabel)
  if((!is.character(test))||(!is.vector(test))||(length(test)>1)
      ||(!any(test==c("t","f","blockf","pairt","wilcoxon","t.equalvar"))))
     stop(paste("your setting of test is",test,"\nthe test needs to be a single character from c('t',f','blockf','pairt','wilcoxon','t.equalvar')"))
  if((!is.integer(as.integer(classlabel))) ||(!is.vector(classlabel)))
     stop("classlabel needs to be just a vector of integers")
  if(any(test==c("t","wilcoxon","t.equalvar"))){
    x<-sum(classlabel==0)
    y<-sum(classlabel==1)
    if((x==0)||(y==0)||(x+y<length(classlabel)))
      stop(paste("in t test, every number in class label needs to be 0 or 1 and neither of the 0 set or 1 set can be empty set\n",
                 "The folllowing is your setting of classlabel",classlabel,"\n"))
  }
  if(test=="f"){
      tab <- table(classlabel)
      tab <- tab[tab>0]
      if(length(tab)<2)
          stop(paste("in F test, we need at least two groups\n",
                     "Your setting of classlabel is", classlabel,
                   "\n"))
      if(sum(tab)-length(tab)<2)
          stop(paste("Insufficient df for denominator of F",
                     "the settings are", classlabel, "\n"))
  }
  if(test=="pairt"){
    K<-max(classlabel)
    if(K!=1)
      stop(paste("in paired t test, we only handle two groups\n",
                 "your classlabel=",classlabel,"\n"))
    if(length(classlabel)%%2==1)
      stop(paste("the classlabel length must be an even number in the paired t\n","your classlabel=",classlabel,"\n"))
    halfn<-length(classlabel)%/%2
    for(i in c(1:halfn)){
      cur<-classlabel[(2*i-1):(2*i)]
      if((sum(cur==0)==0)||(sum(cur==1)==0))
        stop(paste("Some errors in specifying classlabel for the paired t test for the block",i,"located at","(",2*i-1,2*i,")\n",
                   "your classlabel=",classlabel,"\n"))

    }
  }
  if(test=="blockf"){
    K<-max(classlabel)
    if(K<1)
      stop(paste("in blockF test, we need at least two groups\n",
                 "your classlabel=",classlabel,"\n"))
    if(length(classlabel)%%(K+1)>0)
      stop(paste("the classlabel length must be the multiple of the number of treatments in the block test\n","your classlabel=",classlabel,"\n"))
     B<-length(classlabel)%/%(K+1)
    for(i in c(1:B)){
      cur<-classlabel[c((K+1)*(i-1)+1):((K+1)*i)]
      #to check if cur is a permutation of c(0,1,..,K)
      for(j in c(0:K))
        if(sum(cur==j)==0)
          stop(paste("the classlabel has some errors for the blockf test at block",i,"located at",
               "(",(K+1)*(i-1)+1,(K+1)*i,")","There is no elements =",j,"within this block\n","your classlabel=",classlabel,"\n"))
    }
  }
}
mt.checkX<-function(X,classlabel,test){
  if((!is.matrix(X)) || !(is.numeric(X)))
     stop(paste("X needs to be a matrix\n","your X=",X,"\n"))
  if(ncol(X)!=length(classlabel))
    stop(paste("the number of column of X needs to be the same as the lengtho of classlabel\n","your X=",X,"\n your classlabel is",classlabel,"\n"))
  mt.checkclasslabel(classlabel,test)
}
mt.checkV<-function(V,classlabel,test){
  if((!is.vector(V)) || !(is.numeric(V)))
     stop(paste("V needs to be a vector\n","your V=",V,"\n"))
  if(length(V)!=length(classlabel))
    stop("the length of V needs to be the same as the length of classlabel\n",
         "your V=",V,"\n your classlabel=",classlabel,"\n")
  mt.checkclasslabel(classlabel,test)
}

mt.checkothers<-function(side="abs",fixed.seed.sampling="y",B=10000,na=.mt.naNUM,nonpara="n")
{
  if((length(B)>1) || !(is.integer(as.integer(B))) ||(!is.vector(B)))
     stop(paste("B needs to be just a integer\n","your B=",B,"\n"))
   if(B<0)
     stop(paste("the number of Permutations (B) needs to be positive\n, If you want to complete permutation, just specify B as any number greater than the maximum number of permutation\n","your B=",B))
  if((length(na)>1) || !(is.numeric(na)) ||(!is.vector(na)))
     stop(paste("na needs to be just a number\n","your na=",na,"\n"))
  if((!is.character(side))||(!is.vector(side))||(length(side)>1)
     ||(!any(side==c("upper","abs","lower"))))
    stop(paste("the side needs to be a single character from c('upper','abs','lower')\n","your side=",side,"\n"))
  if((!is.character(fixed.seed.sampling))||(!is.vector(fixed.seed.sampling))||(length(fixed.seed.sampling)>1)
     ||(!any(fixed.seed.sampling==c("y","n"))))
    stop(paste("the fixed.seed.sampling needs to be a single character from c('y','n')\n","your fixed.sampling=",fixed.seed.sampling,"\n"))
  if((!is.character(nonpara))||(!is.vector(nonpara))||(length(nonpara)>1)
     ||(!any(nonpara==c("y","n"))))
    stop(paste("the nonpara needs to be a single character from c('y','n')\n","your nonpara=",nonpara,"\n"))
}
mt.transformX<-function(X,classlabel,test,na,nonpara)
{
  X<-mt.number2na(data.matrix(X),na)
  mt.checkX(X,classlabel,test)
  n<-ncol(X)
  if(test=="pairt"){
    if(n%%2==1)
      stop(paste("the number of columns for X must be an even number in the paired t  test\n","your X=",X,"\n your classlabel=",classlabel,
                 "\n your test=",test,"\n"))
    halfn<-n%/%2;
    evendata<-X[,c(1:halfn)*2]
    odddata<-X[,c(1:halfn)*2-1]
    vecX<-(evendata-odddata)
    vecX<-data.matrix(vecX)
  }else{
    vecX<-data.matrix(X)
  }
  if(test=="wilcoxon"||nonpara=="y"){
    for(i in c(1:nrow(vecX))){
      vecX[i,]<-rank(vecX[i,])
    }
  }
  vecX<-mt.na2number(c(vecX),na)
  newL<-mt.transformL(classlabel,test)
  list(X=vecX,m=nrow(X),n=newL$n,classlabel=newL$classlabel)
}
mt.transformV<-function(V,classlabel,test,na,nonpara)
{
  V<-mt.number2na(as.double(V),na)
  mt.checkV(V,classlabel,test)
  n<-length(classlabel)
  if(test=="pairt"){
    if(n%%2==1)
      stop(paste("the number of columns for V must be an even number in the paired t test\n","your V=",V,"\n your classlabel=",classlabel,
                 "\n your test=",test,"\n"))
    halfn<-n%/%2
    evendata<-V[c(1:halfn)*2]
    odddata<-V[c(1:halfn)*2-1]
    newV<-c(evendata-odddata)
  }
  else{
    newV<-V
  }
  if(test=="wilcoxon"||nonpara=="y"){
    newV<-rank(newV)
    }
  newL<-mt.transformL(classlabel,test)
  list(V=mt.na2number(newV,na),n=newL$n,classlabel=newL$classlabel)
}
mt.transformL<-function(classlabel,test)
{
  classlabel<-as.integer(classlabel)
  mt.checkclasslabel(classlabel,test)
  n<-length(classlabel)
  newL<-classlabel
  if(test=="pairt"){
    if(n%%2==1)
      stop(paste("the length of classlabel must be an even number in the pair t\n","your classlabel=",classlabel,"\n your test=",test="\n"))
    halfn<-n%/%2;
    n<-halfn
    newL<-rep(0,n);
    for(i in c(1:n)){
      newL[i]<-classlabel[2*i]
    }
  }
  list(classlabel=newL,n=n)
}
#this functions finds the maximum number of permutation
#if the the initial B=0, or initial B greater than the maximum number of
#permutation maxB, it will return all possible of number of permutation.
mt.getmaxB<-function(classlabel,test,B, verbose=FALSE)
{
  if(B>.mt.BLIM)
    stop(paste("The setting of B=",B,"is too large, Please set B<",.mt.BLIM,"\n"))
  n<-length(classlabel)
  if(test=="pairt"){
    maxB<-2^(n%/%2)
  }
  if(any(test==c("t","f","wilcoxon","t.equalvar"))){
    k<-max(classlabel)
    maxB<-1
    curn<-n
    for(i in c(0:k)){
      nk<-sum(classlabel==i)
      for(j in c(1:nk)){
        maxB<-maxB*curn/j
        curn<-curn-1
      }
    }
  }
  if(test=="blockf"){
    k<-max(classlabel)
    maxB<-1
    for(i in c(1:(k+1))){
      maxB<-maxB*i
    }
    maxB<-maxB^(n%/%(k+1))
  }
  #finished the computing of maxB
  if((B==0)&(maxB>.mt.BLIM)){
    stop(paste("The complete enumeration is too big",maxB,
               "is too large, Please set random permutation\n"))
  }
  if((B>maxB)||(B==0)){
    if(verbose) cat("We'll do complete enumerations\n")
    return(maxB)
  }
  return(B)
}

mt.na2number<-function(x,na){
  y<-x
  y[is.na(y)]<-na
  y
}
mt.number2na<-function(x,na){
  y<-x
  y[y==na]<-NA
  y
}
#patched from the new version
mt.niceres<-function(res,X,index){
  newres<-res
  name<-rownames(X,do.NULL=FALSE,prefix="")
  if(missing(index)) {
    rownames(newres)<-name
  }else {
    rownames(newres)<-name[index]
  }
  newres[abs(newres)>=0.9*1e20]<-NA
  data.frame(newres)
}

Try the multtest package in your browser

Any scripts or data that you put into this service are public.

multtest documentation built on Nov. 8, 2020, 11:03 p.m.