#' Dummy Expantion of a Vector
#'
#' @param x  a vector to be expanded
#' @param type = -1 for non-full-rank design matrix used in SAS proc GLM \cr
#'              = 0  for zero-sum design matrix \cr
#'              = 1  for drop-one-column design matrix \cr
#' @param drop  = "last"   or    "first"  when type != -1\cr
#' @param levels = a string vector consisting of the labels for the levels
#' @param froot = A character to be used to name the columns of X matrix
#' @param sort = 1 to sort the levels as the native factor function does. \cr
#' This is the default behavior of native model.matrix function.
#'
#' @details
#' By default, the zero-sum design matrix with the last level dropped
#' will be generated.
#'
#' @return Design matrix of the size length(x) times length(factor(x))
#' or length(x) times length(factor(x))-1
#'
#' @examples
#' design_expand( c("a","b","c") )
#' design_expand( c("a","xb","c") )
#' design_expand( c("a","b","c"), sort=1 )
#'
#' design_expand( c("a","b","c"), type=-1 )
#' design_expand( c("a","b","c"), levels=c("c","a","b"), type=-1 )
#'
#' design_expand( 1:3, type=0 )
#' design_expand( c("a","b","c"), froot="A" )
#'
#' @export
#'

design_expand <- function( x, type=0, drop="last", levels=NULL
                           , froot="level", sort=0 ){
 # generate desing matrix form a vector consisting of level names
 # Shin-ichi Mayekawa
 # 20150729
 # names: 20150730dnc
 # sort: 20190120
 # levels: 20221021
 #
 # Args:
 #  x           vector or column vector consisting of levels
 #  type        type of desing matrix to be generated
 #              = -1 for non-full-rank design matrix used in SAS proc GLM
 #              = 0  for zero-sum design matrix with the last level omitted
 #              = 1  to drop one column
 #  drop        = "last"   or    "first"
 #

 if( is.factor(x) ) x=as.vector(x)
 else if( is.matrix(x) ) x=as.vector(x)

 if( is.null(levels) ){
  if( sort == 0 ){
   xf=factor( x, levels=unique(x) )
  }
  else{
   xf=factor( x )
  }
 }
 else{
  xf=factor( x, levels=levels )
 }

 X=model.matrix( ~xf-1 )
 attributes(X)=attributes(X)[1:2]
 colnames(X)=paste(froot,1:ncol(X), sep="")

 if( type == 0 ){
  if( drop == "last" ) loc=ncol(X)
  else loc=1
  X[X[,loc]==1,]=-1
  X=X[,-loc,drop=0]
 }
 if( type == 1 ){
  if( drop == "last" ) loc=ncol(X)
  else loc=1
  X=X[,-loc,drop=0]
 }

 return( X )

} # end of design_expand


