R/stats2df.R

#' Produce a dataframe with playerstats
#'
#' \code{stats2df} converts an imported playerstats API object (\code{list}) 
#' to a \code{data.frame}.
#' 
#' The object must have been imported with \code{\link[jsonlite]{fromJSON}} beforehand.
#' To work with achievement datasets, the strings.achievements data needs to be accessible.
#' For the API, see the Wurstmineberg \href{https://github.com/wurstmineberg/api.wurstmineberg.de}{Minecraft API}.
#' @param data A list object containing playerstats as imported by \code{\link[jsonlite]{fromJSON}}
#' @param type The type of dataset: \code{default} or \code{achievements}. Defaults to \code{default}, 
#' which is fine for general, entity and item stats.
#' @param people The dataset containing the people information, defaults to using \code{activePeople}
#' @family playerstats
#' @return A \code{data.frame} containing playerstats
#' @export
#' @note Relies on \link[wurstmineR]{strings.biomes} for \code{achievements} data for classifications.
#' If you want to convert a player's stats JSON file to a \code{data.frame}, 
#' see \link[wurstmineR]{readStatsFile}.
#' @examples
#' \dontrun{
#' generalstats.list <- fromJSON("http://api.wurstmineberg.de/server/playerstats/general.json")
#' generalstats.df   <- stats2df(generalstats.list)
#' }
stats2df <- function(data, people = activePeople, type = "default"){
  if (!("activePeople" %in% ls())){
    people <- getActivePeople()
  }
  if (class(data) != "list"){
    stop("You sure you did that right? Data is not a list.")
  }
  # Spiritual successor to prettyShitUp()
  # First we need to get the nested lists into a nice data.frame
  # Achievements need to be handled separately because of the sublist
  if (type == "achievements"){
    if (!("strings.biomes" %in% ls())){
      strings.biomes           <- getStrings(category = "biomes")
    }

    # Only include biomes relevant to Adventuring Time achievement
    biomes.adv                 <- strings.biomes[strings.biomes$adventuringTime == T, ]
    
    data.df <- plyr::ldply(data, function(player){
      stats <- names(player)
      data.frame(player[stats != "achievement.exploreAllBiomes"])
    }, .id = "player")
    
    # Disable that until I can figure out how to fix it.
    
    # Cleanup missing people
    #data <- data[names(data) %in% activePeople$mc]
    #data.df <- data.df[data.df$player %in% activePeople$mc]
    
    #data.df$exploreAllBiomes.progress <- I(sapply(data, function(x){
    #                                                x$achievement.exploreAllBiomes$progress[x$achievement.exploreAllBiomes$progress %in% biomes.adv$id]
    #                                            }))
    #data.df$exploreAllBiomes.progress.full <- I(sapply(data, function(x){
    #                                                    x$achievement.exploreAllBiomes$progress
    #                                                  }))
    #data.df$exploreAllBiomes.value    <- sapply(data, function(x){
    #                                            x$achievement.exploreAllBiomes$value
    #                                            })
    #data.df$exploreAllBiomes.count    <- sapply(data.df$exploreAllBiomes.progress, length)
    
  } else {
    # Everything else can be handled quite simply
    data.df <- plyr::ldply(data, data.frame, .id = "player")
  }
  # Removing "stat." and "achievement." prefixes from column names
  names(data.df) <- sub("stat.", "", names(data.df))
  names(data.df) <- sub("achievement.", "", names(data.df))
  # Sorting according to people, reordering the rows and factor levels
  data.df        <- data.df[match(people$mc, data.df$player), ]
  data.df$player <- factor(people$name, levels = people$name, ordered = T)
  # Nullifying NAs for plotting reasons
  data.df[is.na(data.df)] <- 0
  
  return(data.df)
}
jemus42/wurstmineR documentation built on May 19, 2019, 4:03 a.m.