#' @title A wrapper to aggregate that gives a wide view of results
#' 
#' @param x data.frame 
#' @param what vector of length
#' @param fun function
#'
#' @return A matrix of result
#' @export
#'
#' @encoding UTF-8
#' 
#' @examples
#' x = data.frame(
#'     gender = sample(c("H", "F"), 20, replace = TRUE),
#'     region = sample(c("east", "west", "south", "north"), 20, replace = TRUE),
#'     wealth = round(runif(20) * 10000),
#'     size = round(runif(20) * 50 + 150)
#' )
#' aggregate_wide(x)
#' aggregate_wide(x, c("region", "gender", "wealth"))
#' aggregate_wide(x, c("region", "gender", "size"))
#' aggregate_wide(x, c("region", "gender", "wealth"), mean)

aggregate_wide = function(x, what, fun = sum) {
    if (missing(what)) what = 1:3
    if (!is.vector(what) && length(what) == 3) {
        stop("what should be a vector of length 3")
    }

    result = stats::aggregate(
        x[what[3]],
        x[c(what[1], what[2])],
        fun,
        drop = FALSE,
        na.rm = TRUE
    )
    result = stats::reshape(
        result,
        direction = "wide",
        idvar = names(result)[1],
        timevar = names(result)[2]
    )
    result = structure(
        as.matrix(result[-1]),
        dimnames = list(
            result[[1]],
            gsub("^.*[.]", "", names(result)[-1]))
    )
    return(result)
}
