#' Inside-Out table
#'
#' @param x Input vector matrix
#' @param id id to be used instead of rownames(x).
#' @param var sas-like abbreviated list of variables to be used.
#' @param rank = 1 to retrun the rank in stead of the row name.
#' @param abs = 1 to use the absolute value of x to sort.
#' @param descending = 0 to sort ascendingly.
#' @param dec a vector indicating if the sort is descending order
#' for each varaible.
#' @param mark A character to mark the negative numbers.
#' @param print = 1 to print the result.
#' @details
#'  This function sort the id according to the magnitude of each variable.\cr
#'  When rank = 0 and abs = 1, those names corresponding to\cr
#'    the negative values  will be marked by - sign. \cr
#' @examples
#' data <- matrix(c(c(2,1,4,5,3),1:5),,2)
#' rownames(data) <- paste("r",1:5,sep="")
#' colnames(data) <- paste("v",1:2,sep="")
#' data[4,2]=-9
#' iotable( data, descending=1, print=0 )
#' iotable( data, descending=1, abs=1, print=0 )
#'
#' @return A vector or matrix of the same size as x.
#'
#' @export
#'

iotable <- function( x, id=NULL, var=NULL, rank=0, abs=0, descending=1
                     , dec=NULL, mark="-", print=1 ){
 # inside-out table
 # Shin-ichi Mayekawa
 # 20140520,21
 # id as an argument: 20140527
 # var as an argument: 20140528
 #
 # Args:
 #
 #     x      vector or matrix whose (row) names are to be printed
 #     id     id variable name to be used
 #     var    sas-like abbreviated variable list
 #     rank   = 1 to retrun the rank in stead of the row name
 #     descending = 1 to sort descendingly for all variables
 #     dec    vector indicating if the sort is descending order
 #     abs    = 1 to use the absolute value of x
 #
 # Values:
 #
 #     vector or matrix of names sorted according to the magnitude
 #     of each variable
 #     or
 #     rank for each variable
 #
 #     When rank = 0 and abs = 1, those names corresponding to
 #     the negative values  will be marked by - sign.
 #
 #
 # Needs:
 #
 #     varlist, loceq
 #

 # variable selection and ordering by varlist
 if( !is.null(var) ){
  temp=varlist( var, colnames(x), 1)
  varf=temp[[2]]
  loc=temp[[2]]
  rm(temp)
  # Print(var,varf,colnames(x),loc)
  x=x[,loc]
 }

 # abs?
 if( abs > 0 ){
  locneg=sign(x)
  if( length(locneg) > 0 ) x=abs(x)
  else abs=0
 }

 # if input is a vector
 if( is.vector(x) ){
  if( rank == 0 ){
   od=order(x, decreasing=descending)
   if( is.null(id) ) name=names(x) else name=id
   if( is.null(name) ) name=paste("r",1:length(x),sep="")
   res=name[od]
   if( abs > 0 ){
    locneg1=which(locneg[od]<0)
    res[locneg1]=paste(mark,res[locneg1],sep="")
   }
  }
  else {
   res=rank(x)
   if( descending == 1 ) res=length(x)-res+1
  }
  return( res )
 }

 # here x is a matrix
 nr=nrow(x)
 if( is.null(id) ){
  name=rownames(x)
  if( is.null(name) ) name=paste("r",1:nrow(x),sep="")
 }
 else name=id
 nc=ncol(x)

 # descending or not
 if( is.null(dec) ){
  dec=rep(0,nc)
  if( descending > 0 ) dec=rep(1,nc)
 }
 else{
  if( length(dec) != nc ){
   cat("\nerror1:(io_plot) length(dec) must be equal to # of columns.\n")
   return( NULL )
  }
 }

 # main body
 if( rank == 0 ){
  res=apply( x, 2, function(y)name[order(y, decreasing=dec)] )
  rownames(res)=1:nrow(res)
  if( abs > 0 ){
   for( j in 1:nc ){
    od=order(x[,j], decreasing=dec)
    locneg1=which( locneg[od,j] < 0 )
    res[locneg1,j]=paste(mark,res[locneg1,j],sep="")
   }
  }
 }
 else{
  res=apply( x, 2, rank )
  for( j in 1:nc ){
   if( dec[j] == 1 ) res[,j]=nr-res[,j]+1
  }
 }

 if( print > 0 ){
  cat("\n\nInside-Out Table\n")
  cat(" # of observations =", nr, ",   # of varaibles =", nc
      , "\n descending =", descending, ",  abs =", abs,"\n")
  print(res,quote=0)
 }

 return( res )

} # end of iotable




#' Profile Plot
#'
#' @param df data frame
#' @param var sas-like abbreviated list of variables to be used.
#' @param standard = 1 to standardize the variables \cr
#' = 2 to scale the variables using min and max
#' @param title plot title string.
#' @param  pty A vector to specify point symbol: \cr
#'     Default 16 (closed circle), if you don't plot data points, \cr
#'       it should be 32. This is repeatedly used for data series. \cr
#' @param  pcol  A vector of color codes for plot data: \cr
#'      Default 1:8, which are repeatedly used.
#' @param  plty  A vector of line types for plot data: \cr
#'      Default 1:6, which are repeatedly used.
#' @param  plwd   A vector of line widths for plot data: \cr
#'    Default 1, which is repeatedly used.
#' @param  ... Miscellaneous arguments to be given for plot.
#' @param  legend  = 1 to display legend.
#' @param  lpos  upper left corner of the legend.
#' @param  lcex  font size for the legend.
#' @param  llwd  line width for the legend.
#' @param  lbty  the type of box to be drawn around the legend.
#' @param  pch plot character
#' @param  lwd line width
#' @param  nobspc # of observations in one chart.
#' @param  across # of graphs in a row.
#' @param  down # of graphs in a column.
#' @param  mar margins for multiple graphs per page.
#' @param  axislabcol not used.
#' @param  vlabels not used.
#' @param  caxislabels  not used.
#' @param  paxislabels not used.
#'
#' @examples
#' data=data.frame(a=c(1,2,3,4),b=c(0,1,0,1),c=c(4,3,2,1))
#' pplot( data)
#' pplot( data, nobspc=2 )
#' pplot( data, nobspc=2, across=2 )
#'
#' @return None
#' @export
#'

pplot <- function(  df, var=NULL, pty=16, pcol = 1:8, pch=2, lwd=2
                    , plty = 1:8, plwd = 2, axislabcol = "blue"
                    , title = ""
                    , vlabels = NULL, caxislabels = NULL, paxislabels = NULL
                    , legend=1, lpos=c(1.5,-.2), lcex=1, llwd=1, lbty="n"
                    , standard=0, nobspc=0, down=1, across=1
                    , mar=c(8,2,1,2)
                    , ... ){
 # profile plot
 # Shin-ichi Mayekawa
 # 20140601,02
 # bugfix: 20140604
 # standard: 20140604,05
 # nobspc=1: 20140610 dnc
 # remove non-numeric variables: 20140610
 # standard == 0: 20151021
 #

 # Args:
 #

 #  df
 #      The data frame to be used to draw profile plot.
 #      The number of columns (variables) must be more than 2.

 #  var
 #      abbreviated list of variables to be used

 #  axistype
 #      The type of axes, specified by any of 0:5. 0 means no axis label. #
 #      1 means center axis label only. 2 means around-the-chart label only.
 #      3 means both center and around-the-chart (peripheral) labels.
 #      4 is *.** format of 1, 5 is *.** format of 3. Default is 0.

 #  seg
 #      The number of segments for each axis (default 4).

 #  pty
 #      A vector to specify point symbol:
 #      Default 16 (closed circle), if you don't plot data points,
 #      it should be 32. This is repeatedly used for data series.
 #  pcol
 #      A vector of color codes for plot data:
 #      Default 1:8, which are repeatedly used.
 #  plty
 #      A vector of line types for plot data:
 #      Default 1:6, which are repeatedly used.
 #  plwd
 #      A vector of line widths for plot data:
 #      Default 1, which is repeatedly used.

 #  title
 #      if any, title should be typed.
 #  maxmin
 #      Logical. If true, data frame includes possible maximum values as row 1
 #      and possible minimum values as row 2.
 #      If false, the maximum and minimum values for each axis will be
 #       calculated as actual maximum and minimum of the data. Default TRUE.
 #  ...
 #      Miscellaneous arguments to be given for plot.default().
 #
 #  legend
 #      = 1 to display legend
 #  lpos
 #      upper left corner of the legend
 #  lcex
 #      font size for the legend
 #  llwd
 #
 #  lbty
 #
 #
 #  standard
 #      = 1  each variable will be standardized and
 #      the graph will be drawn  using ylim=c( min(dfs), max(dfs) )
 #      = 2
 #      Othersize, each variable will be scaled so that min=0 and max=1.
 #
 #  nobspc
 #      # of observations in one chart
 #
 #  across
 #      # of graphs in a row
 #  down
 #      # of graphs in a column
 #  mar
 #      margins for multiple graphs per page

 #
 # Values:
 #
 #

 # Needs:
 #
 #    varlist, loceq, standard, vartype
 #




 # const
 nobs=nrow(df)
 nvar=ncol(df)

 # errors
 if( nvar < 2 ){
  cat("The number of variables must be 3 or more.\n")
  return()
 }


 # variable selection and ordering by varlist
 if( !is.null(var) ){
  temp=varlist( var, colnames(df), 1)
  varf=temp[[2]]
  loc=temp[[2]]
  rm(temp)
  # Print(var,varf,colnames(x),loc)
  df=df[,loc]
  nvar=ncol(df)
 }

 if (!is.data.frame(df)) {
  #  cat("The data must be given as dataframe.\n")
  # return()
  df=as.data.frame(df)
 }
 if( is.null(rownames(df)) ) rownames(df)=paste("r",1:nobs,sep="")


 # convert factors to integer
 loc=which( vartype(df) == "factor" )
 if( length(loc) > 0 ) df[,loc]=as.integer(df[,loc])
 # renove non-numeric variables
 loc=vartype(df)
 loc=which( loc == "numeric" )
 if( length(loc) <= 2 ){
  cat("The number of numeric variables must be 3 or more.\n")
 }
 else df=df[,loc,drop=0]
 nvar=ncol(df)

 # standardization or minmax
 if( standard == 1 ){
  dfs=standard(df)
  ylim=c(min(dfs),max(dfs))
 }
 else if( standard == 2 ){
  # for each variable, make min=0 and max=1
  dfmax <- apply(df, 2, max)
  dfmin <- apply(df, 2, min)
  dfs=t( (t(df)-dfmin)/(dfmax-dfmin) )
  rownames(dfs)=rownames(df)
  ylim=0:1
 }
 else{
  dfs=df
  ylim=c(min(dfs),max(dfs))
 }


 # graphical parameters
 if( across < 1  |  across > 14 ){
  cat("\nwarning1:(pplot)  across must be in 1:14.   Set to one.\n")
  across=1
 }
 if( down < 1  |  down > 14 ){
  cat("\nwarning1:(pplot)  down must be in 1:14.   Set to one.\n")
  down=1
 }
 # save the current graphical parameter
 oldpar <- par(no.readonly = TRUE)

 # set the graphical parameters
 par(mfrow = c(down,across), mar=mar + 0.1, xpd=TRUE)

 # main plot type, color etc
 if (length(pty)  < nobs)   ptys = rep(pty, nobs) else  ptys = pty
 if (length(pcol) < nobs)   pcols = rep(pcol, nobs) else   pcols = pcol
 if (length(plty) < nobs)   pltys = rep(plty, nobs) else   pltys = plty
 if (length(plwd) < nobs)   plwds = rep(plwd, nobs) else  plwds = plwd


 # nobspc observations in one chart
 if( nobspc == 0 ) nobspc=nobs
 nobspc=min(nobspc,nobs)
 nloop=ceiling(nobs/nobspc)


 # loop for each chart
 for( llll in 1:nloop ){

  fromto=( (llll-1)*nobspc+1 ):min(llll*nobspc,nobs)
  nobsllll=min(nobspc,length(fromto))

  # matplot
  matplot( t(dfs[fromto,,drop=0]), type="b", pch=pch, lwd=lwd, lty=pltys[fromto]
           , xaxt="n", ylim=ylim
           , ylab="", main=title, col=pcols[fromto] )
  axis(1, at = 1:ncol(dfs), labels=colnames(dfs), cex.axis = 1)
  legend( lpos[1],ylim[1]+lpos[2]*(ylim[2]-ylim[1])
          , rownames(dfs[fromto,,drop=0])
          , col=pcols[fromto], lty=pltys[fromto]
          , cex=lcex, lwd=llwd, merge=1, ncol=nobsllll, bty=lbty )

 } # end of llll loop

 on.exit(par(oldpar))


} # end of pplot



#' Radar Chart
#'
#'  This is a modified version of \code{radarchart} in \code{fmsb} package.
#'
#' @param df data frame
#' @param var sas-like abbreviated list of variables to be used.
#' @param standard = 1 to standardize the variables
#' @param title plot title string.

#' @param axistype The type of axes, specified by any of 0:5. \cr
#'    0 means no axis label. \cr
#'    1 means center axis label only. 2 means around-the-chart label only. \cr
#'    3 means both center and around-the-chart (peripheral) labels. \cr
#'    4 is *.** format of 1, 5 is *.** format of 3. Default is 0. \cr

#' @param seg The number of segments for each axis (default 4).


#' @param  pty A vector to specify point symbol: \cr
#'     Default 16 (closed circle), if you don't plot data points, \cr
#'       it should be 32. This is repeatedly used for data series. \cr
#' @param  pcol  A vector of color codes for plot data: \cr
#'      Default 1:8, which are repeatedly used.
#' @param  plty  A vector of line types for plot data: \cr
#'      Default 1:6, which are repeatedly used.
#' @param  plwd   A vector of line widths for plot data: \cr
#'    Default 1, which is repeatedly used.


#' @param  pdensity A vector of filling density of polygons: \cr
#'      Default NULL, which is repeatedly used.
#' @param pfcol A vector of color codes for filling polygons: \cr
#'      Default NA, which is repeatedly usd.
#' @param pangle angle
#' @param  cglty Line type for radar grids: Default 3, which means dotted line.
#' @param  cglwd Line width for radar grids: Default 1,
#' which means thinnest line.
#' @param  cglcol Line color for radar grids: Default "navy"
#' @param  axislabcol Color of axis label and numbers: Default "blue"
#'
#' @param  centerzero Logical. If true, this function draws charts with scaling
#'      originated from (0,0). \cr
#'      If false, charts originated from (1/segments). Default FALSE.
#' @param  vlabels Character vector for the names for variables. \cr
#'      If NULL, the names of the variables as colnames(df) are used.
#' @param  caxislabels  Character vector for center axis labels, \cr
#'      overwriting values specified in axistype option. \cr
#'      If NULL, the values specified by axistype option are used.
#' @param  caxisoffset offset
#'
#' @param  caxiscex cex
#'
#' @param  paxislabels Character vector for around-the-chart (peripheral)
#'  labels, \cr
#'      overwriting values specified in axistype option. \cr
#'      If NULL, the values specified by axistype option are used.
#' @param  clockwise = 1 if the graph places the variables in clockwise
#' from the top
#' @param  frame = 1 to draw frame around the graph

#' @param  legend  = 1 to display legend.
#' @param  lpos  upper left corner of the legend.
#' @param  lcex  font size for the legend.
#' @param  llwd  line width for the legend.

#' @param  nobspc # of observations in one chart.
#' @param  across # of graphs in a row.
#' @param  down # of graphs in a column.
#' @param  mar margins for multiple graphs per page.
#' @param  ... additional parameters for plot
#'
#' @examples
#' data=data.frame(a=c(1,2,3,4),b=c(0,1,0,1),c=c(4,3,2,1))
#' radarchart( data, nobspc=2, across=2, lpos=c(.9,.1) )
#'
#' @return None
#' @export
#'

radarchart <- function(
 df, var=NULL, axistype = 4, seg = 4, pty = 16, pcol = 1:8
 , plty = 1:8, plwd = 1, pdensity = NULL, pangle = 45, pfcol = NA
 , cglty = 3, cglwd = 1, cglcol = "navy", axislabcol = "blue"
 , title = "", centerzero = FALSE
 , vlabels = NULL, caxislabels = NULL, paxislabels = NULL
 , frame=1, clockwise=1, caxisoffset=-.1, caxiscex=.9
 , legend=1, lpos=c(1.1,-.1), lcex=.8, llwd=1
 , standard=0, nobspc=0, down=1, across=1
 , mar=c(1, 1, 1, 1)
 , ... ){
 #
 # Radar Chart
 # original found in fmsb package
 # Shin-ichi Mayekawa
 # 20140527,28,29
 # nobspc, down, across: 20140601
 # var: 20140601,02
 # llwd: 20140603
 # standardization: 20140605
 # nobspc=1: 20140610 dnc
 # remove non-numeric variables: 20140610
 # standard == 0: 20151021
 #

 # Args:
 #

 #  df
 #      The data frame to be used to draw radarchart.
 #      The number of columns (variables)  must be more than 2.

 #  var
 #      abbreviated list of variables to be used

 #  axistype
 #      The type of axes, specified by any of 0:5. 0 means no axis label. #
 #      1 means center axis label only. 2 means around-the-chart label only.
 #      3 means both center and around-the-chart (peripheral) labels.
 #      4 is *.** format of 1, 5 is *.** format of 3. Default is 0.

 #  seg
 #      The number of segments for each axis (default 4).

 #  pty
 #      A vector to specify point symbol:
 #      Default 16 (closed circle), if you don't plot data points,
 #      it should be 32. This is repeatedly used for data series.
 #  pcol
 #      A vector of color codes for plot data:
 #      Default 1:8, which are repeatedly used.
 #  plty
 #      A vector of line types for plot data:
 #      Default 1:6, which are repeatedly used.
 #  plwd
 #      A vector of line widths for plot data:
 #      Default 1, which is repeatedly used.
 #  pdensity
 #      A vector of filling density of polygons:
 #      Default NULL, which is repeatedly used.
 #  pfcol
 #      A vector of color codes for filling polygons:
 #      Default NA, which is repeatedly usd.
 #  cglty
 #      Line type for radar grids: Default 3, which means dotted line.
 #  cglwd
 #      Line width for radar grids: Default 1, which means thinnest line.
 #  cglcol
 #      Line color for radar grids: Default "navy"
 #  axislabcol
 #      Color of axis label and numbers: Default "blue"

 #  title
 #      if any, title should be typed.
 #  centerzero
 #      Logical. If true, this function draws charts with scaling
 #      originated from (0,0).
 #      If false, charts originated from (1/segments). Default FALSE.
 #  vlabels
 #      Character vector for the names for variables.
 #      If NULL, the names of the variables as colnames(df) are used.
 #      Default NULL.
 #  caxislabels
 #      Character vector for center axis labels,
 #      overwriting values specified in axistype option.
 #      If NULL, the values specified by axistype option are used.
 #      Default is NULL.
 #  caxisoffset
 #
 #  caxiscex
 #
 #  paxislabels
 #      Character vector for around-the-chart (peripheral) labels,
 #      overwriting values specified in axistype option.
 #      If NULL, the values specified by axistype option are used.
 #      Default is NULL.
 #  ...
 #      Miscellaneous arguments to be given for plot.default().
 #
 #  clockwise
 #      = 1 if the graph places the variables in clockwise from the top
 #  frame
 #      = 1 to draw frame around the graph
 #  legend
 #      = 1 to display legend
 #  lpos
 #      upper left corner of the legend
 #  lcex
 #      font size for the legend
 #
 #  standard
 #      When standard == 1 each variable will be standardized and
 #      the graph will be drawn  using ylim=c( min(dfs), max(dfs) )
 #      Othersize, each variable will be scaled so that min=0 and max=1.
 #
 #  nobspc
 #      # of observations in one chart
 #  across
 #      # of graphs in a row
 #  down
 #      # of graphs in a column
 #  mar
 #      margins for multiple graphs per page
 #

 #
 # Values:
 #
 #

 # Needs:
 #
 #    varlist, loceq, standard, vartype
 #


 initialize_web <- function(){

  # initialize plot
  plot(c(-1.2, 1.2), c(-1.2, 1.2), type = "n", frame.plot = frame
       , axes = FALSE, xlab = "", ylab = "", main = title, asp = 1
       , ...)

  # drawing empty web and axis
  for (i in 0:seg) { # for each level
   polygon(xx * (i + CGap)/(seg + CGap), yy * (i + CGap)/(seg + CGap)
           , lty = cglty, lwd = cglwd, border = cglcol)
   if (axistype == 1 | axistype == 3)
    CAXISLABELS <- paste(i/seg * 100, "(%)")
   if (axistype == 4 | axistype == 5)
    CAXISLABELS <- sprintf("%3.2f", i/seg)
   if (!is.null(caxislabels) & (i < length(caxislabels)))
    CAXISLABELS <- caxislabels[i + 1]
   if (axistype == 1 | axistype == 3 | axistype == 4 | axistype == 5)
    text(caxisoffset, (i + CGap)/(seg + CGap), CAXISLABELS
         , col = axislabcol, cex=caxiscex )
  } # end of i loop

  if (centerzero) {
   arrows(0, 0, xx * 1, yy * 1
          , lwd = cglwd, lty = cglty, length = 0, col = cglcol)
  }
  else {
   arrows(xx/(seg + CGap), yy/(seg + CGap), xx * 1, yy * 1
          , lwd = cglwd, lty = cglty, length = 0, col = cglcol)
  }

  # axis labels
  PAXISLABELS <- colnames(df)
  if (!is.null(paxislabels))
   PAXISLABELS <- paxislabels
  if (axistype == 2 | axistype == 3 | axistype == 5) {
   text(xx[1:nvar], yy[1:nvar], PAXISLABELS, col = axislabcol)
  }
  VLABELS <- colnames(df)
  if (!is.null(vlabels)) VLABELS <- vlabels
  text(xx * 1.2, yy * 1.2, VLABELS)

 } # end of initialize_web





 # const
 nobs=nrow(df)
 nvar=ncol(df)

 # errors
 if ((nvar <- length(df)) <= 2) {
  cat("The number of variables must be 3 or more.\n")
  return()
 }

 # variable selection and ordering by varlist
 if( !is.null(var) ){
  temp=varlist( var, colnames(df), 1)
  varf=temp[[2]]
  loc=temp[[2]]
  rm(temp)
  # Print(var,varf,colnames(x),loc)
  df=df[,loc]
  nvar=ncol(df)
 }


 # reverse col order
 if( clockwise ) df=df[,c(1,nvar:2)]

 if (!is.data.frame(df)) {
  #  cat("The data must be given as dataframe.\n")
  # return()
  df=as.data.frame(df)
 }

 # convert factors to integer
 loc=which( vartype(df) == "factor" )
 if( length(loc) > 0 ) df[,loc]=as.integer(df[,loc])
 # renove non-numeric variables
 loc=vartype(df)
 loc=which( loc == "numeric" )
 if( length(loc) <= 2 ){
  cat("The number of numeric variables must be 3 or more.\n")
 }
 else df=df[,loc,drop=0]
 nvar=ncol(df)


 # standardization or minmax
 if( standard == 1 ){
  dfs=standard(df)
  minmax=c(min(dfs),max(dfs))
  # minmax=closest( ylim, seq(-3,3,length.out=21) )
  dfs=t( (t(dfs)-minmax[1])/(minmax[2]-minmax[1]) )
  rownames(dfs)=rownames(df)
  caxislabels=seq(minmax[1],minmax[2],length.out=seg+1)
  caxislabels=formatC(caxislabels,1,4,format="f")
 }
 else if( standard == 2 ){
  # for each variable, make min=0 and max=1
  dfmax <- apply(df, 2, max)
  dfmin <- apply(df, 2, min)
  dfs=t( (t(df)-dfmin)/(dfmax-dfmin) )
  rownames(dfs)=rownames(df)
  ylim=0:1
 }
 else{
  dfs=df
  minmax=c(min(dfs),max(dfs))
  # minmax=closest( ylim, seq(-3,3,length.out=21) )
  dfs=t( (t(dfs)-minmax[1])/(minmax[2]-minmax[1]) )
  rownames(dfs)=rownames(df)
  caxislabels=seq(minmax[1],minmax[2],length.out=seg+1)
  caxislabels=formatC(caxislabels,1,4,format="f")
 }



 # initialize plot
 theta <- seq(90, 450, length = nvar + 1) * pi/180
 theta <- theta[1:nvar]
 xx <- cos(theta)
 yy <- sin(theta)
 rm(theta)
 CGap <- ifelse(centerzero, 0, 1)

 # main plot type, color etc
 if (length(pty)  < nobs)   ptys = rep(pty, nobs) else  ptys = pty
 if (length(pcol) < nobs)   pcols = rep(pcol, nobs) else   pcols = pcol
 if (length(plty) < nobs)   pltys = rep(plty, nobs) else   pltys = plty
 if (length(plwd) < nobs)   plwds = rep(plwd, nobs) else  plwds = plwd
 if (length(pdensity) < nobs)  pdensities = rep(pdensity, nobs) else
  pdensities = pdensity
 if (length(pangle) < nobs)  pangles = rep(pangle, nobs) else pangles = pangle
 if (length(pfcol)  < nobs)  pfcols = rep(pfcol, nobs) else  pfcols = pfcol

 CGr=CGap/(seg + CGap)
 segr=seg/(seg + CGap)


 # graphical parameters
 if( across < 1  |  across > 14 ){
  cat("\nwarning1:(radarchart)  across must be in 1:14.   Set to one.\n")
  across=1
 }
 if( down < 1  |  down > 14 ){
  cat("\nwarning1:(radarchart)  down must be in 1:14.   Set to one.\n")
  down=1
 }
 # save the current graphical parameter
 oldpar <- par(no.readonly = TRUE)

 # set the graphical parameters
 par(mfrow = c(down,across), mar=mar + 0.1)


 # nobspc observations in one chart
 if( nobspc == 0 ) nobspc=nobs
 nloop=ceiling(nobs/nobspc)

 # loop for each chart
 for( llll in 1:nloop ){

  # clear and drow empty web
  initialize_web()

  fromto=( (llll-1)*nobspc+1 ):min(llll*nobspc,nobs)

  for( i in fromto ){

   scale=CGr+dfs[i,]*segr

   xxs=xx*scale  # sin*scale
   yys=yy*scale  # cos*scale

   if (is.null(pdensities)) {
    polygon( xxs, yys, lty = pltys[i], lwd = plwds[i]
             , border = pcols[i], col = pfcols[i] )
   } else {
    polygon( xxs, yys, lty = pltys[i], lwd = plwds[i]
             , border = pcols[i]
             , density = pdensities[i], angle = pangles[i], col = pfcols[i] )
   } # end of pdensities

   points(xxs, yys, pch = ptys[i], col = pcols[i])

  } # end of i loop

  legend(lpos[1],lpos[2], rownames(dfs[fromto,,drop=0]), col=pcols[fromto]
         , cex=lcex,  lwd=llwd, merge = TRUE)

 } # end of llll loop

 on.exit(par(oldpar))


} # end of radarchart
