Reputation: 109
I'm prototyping a dashboard (R Shiny) to create density plots that can be customized to graph BMI of Hernia patients by different categories, namely Gender, Race, Ethnicity, and Smoker. The categories Gender, Ethnicity, and Smoker all seem to be working perfectly fine, however attempting to plot BMI by Race fails when I run the app and use the drop down menus to select the category 'Race'. Instead, I receive the message, "Error: 'x' and 'units' must have length > 0", which is mystifying. Other posts with the similar error message on Stack Overflow suggest coercing the racial categories to lower case, which I attempted (i.e., df$Race = tolower(df$Race), but that didn't seem to help.
Categories of Race include:
Of these, it appears that our data includes only 1 patient who identifies as 'American Indian or Alaska Native'.
Below you will find the code I've written for 'app.R', and the code I use to plot the data.
First, app.R:
#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(shiny)
library(DBI)
library(dplyr)
library(DT)
library(tibble)
source("connect.R")
source("density.R")
con = connect()
myquery = as_tibble(dbGetQuery(con,
"SELECT
pat.lngPatientID PatID,
pat.lngMRN MRN,
pat.strFirstName FirstName,
pat.strLastName LastName,
pat.dteBirth DOB,
pat.lngHeight Height,
pat.lngWeight Weight,
pat.lngBMI BMI,
tpg.strValue Gender,
tpr.strValue Race,
eth.strValue Ethnicity,
tss.strValue Smoker
FROM tblPatient pat
LEFT JOIN tlkpGender tpg
ON pat.lngGender = tpg.lngValue
LEFT JOIN tlkpRace tpr
ON pat.lngRace = tpr.lngValue
LEFT JOIN tlkpEthnicity eth
ON pat.lngEthnicity = eth.lngValue
LEFT JOIN tlkpSmokingStatus tss
ON pat.strSmokingStatus = tss.lngValue "
)
)
df = na.omit(myquery)
# Define UI
ui <- fluidPage(
titlePanel("BMI of Hernia Patients"),
sidebarLayout(
sidebarPanel(
helpText("Create BMI density plots from the HHC Hernia Database."),
selectInput("variable",
label = "Choose a variable to display",
choices = list("BMI"),
selected = "BMI"),
selectInput("category",
label = "Choose a category to graph BMI by",
choices = list("Gender",
"Race",
"Ethnicity",
"Smoker"),
selected = "None"),
sliderInput("range",
label = "Display Range:",
min = 0, max = 100, value = c(0, 65))
),
mainPanel(
# DT::dataTableOutput("mytable"),
plotOutput("dense_plot")
)
)
)
# Define server logic
server <- function(input, output) {
#output$mytable = DT::renderDataTable({myquery})
output$dense_plot = renderPlot({
var = switch(input$variable,
"BMI" = df$BMI)
cat = switch(input$category,
"Gender" = df$Gender,
"Race" = df$Race,
"Ethnicity" = df$Ethnicity,
"Smoker" = df$Smoker)
density_plots(dataset = df,
variable = var,
category = cat,
x_label = "BMI",
title_card = "Distribution of BMI",
lower = input$range[1],
upper = input$range[2])
})
}
# Run the app
shinyApp(ui = ui, server = server)
Next, we've density.R, which contains two functions density_plot()
which creates a single density plot for BMI of all patients, and density_plots()
which creates a density plot of BMI by a specific category. This second function is what I'm calling in app.R
library(ggplot2)
density_plot <- function(dataset, variable, rm_na = TRUE, border_color = "darkgoldenrod4", fill_color = "dodgerblue4", transparency = 0.25, lower = 0, upper = 65,
title_card = "", x_label = "") {
# plots a single density plot. Defaults are set to appropriate values for Hernia BMI.
ggplot(data = dataset) +
geom_density(mapping = aes(x = variable), na.rm = rm_na, color = border_color, fill = fill_color, alpha = transparency) +
scale_x_continuous(limits = c(lower, upper)) +
coord_cartesian(xlim = c(lower, upper)) +
labs(x = x_label, title = title_card)
}
density_plots <- function(dataset, variable, category, rm_na = TRUE, transparency = 0.25, lower = 0, upper = 65, title_card = "", x_label = "") {
ggplot(data = dataset) +
geom_density(mapping = aes(x = variable, color = category, fill = category), na.rm = rm_na, alpha = transparency) +
scale_x_continuous(limits = c(lower, upper)) +
coord_cartesian(xlim = c(lower, upper)) +
labs(x = x_label, title = title_card)
}
Upvotes: 0
Views: 166
Reputation: 6954
Its hard to debug this since its not reproducible but you can try this:
# Define server logic
server <- function(input, output) {
#output$mytable = DT::renderDataTable({myquery})
output$dense_plot = renderPlot({
density_plots(dataset = df,
variable = input$variable,
category = input$category,
x_label = "BMI",
title_card = "Distribution of BMI",
lower = input$range[1],
upper = input$range[2])
})
}
density_plots <- function(dataset,
variable,
category,
rm_na = TRUE,
transparency = 0.25,
lower = 0, upper = 65,
title_card = "", x_label = "") {
ggplot(data = dataset) +
geom_density(mapping = aes_string(x = variable, color = category, fill = category),
na.rm = rm_na, alpha = transparency) +
scale_x_continuous(limits = c(lower, upper)) +
coord_cartesian(xlim = c(lower, upper)) +
labs(x = x_label, title = title_card)
}
Upvotes: 0