### fn.stata.type.R
###------------------------------------------------------------------------------------------
### What: function to determine the STATA storage type from variable data
### Time-stamp: <2017-11-30 11:21:27 assyst>
###-------------------------------------------------------------------------------------------

stata.datatype <- function(data,
                      ...)
{
    tryCatch({
    data <- as.numeric(data)
    ## --- Setup ---
    # Get the number of decimal places
    decimalplaces <- lapply(data,function(x) {
        if (!is.na(x) && (x %% 1) != 0) {
            nchar(strsplit(sub('0+$', '', as.character(x)), ".", fixed=TRUE)[[1]][[2]])
        } else {
            0
        }
    })

    ## Numeric data types and value ranges
    #  Reference - http://wlm.userweb.mwn.de/wstatvar.htm
    #  byte	integer values between -127 and 100
    #  int	integer values between -32,767 and 32,740
    #  long	integer values between -2,147,483,647 and 2,147,483,620
    #  float	real numbers (i.e. numbers with decimal places) with about 8 digits of accuracy
    #  double	real numbers (i.e. numbers with decimal places) with about 16 digits of accuracy

    type <- double

    maxdecimalplaces <- max(as.numeric(decimalplaces))

    if (maxdecimalplaces > 8) {
        # double - real value with about 16 digits of accuracy
        type <- "double"
    } else if (maxdecimalplaces > 0) {
        # float - real value with about 8 digits of accuracy
         type <- "float"
    } else {
        # integer values
        minValue <- min(as.numeric(data), na.rm=T)
        maxValue <- max(as.numeric(data), na.rm=T)

        if( minValue > -127 && maxValue < 100 ){
            # byte -    integer values between -127 and 100
            type <- "byte"
        } else if( minValue > -32767 && maxValue < 32740 ){
            # int -     integer values between -32,767 and 32,740
            type <-"int"
        } else{
            # long -	integer values between -2,147,483,647 and 2,147,483,620
            type <- "long"
        }
    }

    return(type)
    }, error = function(err) {
        return("double")
    })

}

