【问题标题】:Unable to resolve R Shiny error, "'x' and 'units' must have length > 0" when attempting to render a (ggplot) density plot尝试渲染(ggplot)密度图时,无法解决 R Shiny 错误,“'x' 和 'units' 的长度必须 > 0”
【发布时间】:2021-11-14 11:51:08
【问题描述】:

我正在对仪表板 (R Shiny) 进行原型设计,以创建可自定义的密度图,以按不同类别(即性别、种族、民族和吸烟者)绘制疝气患者的 BMI 图表。性别、种族和吸烟者类别似乎都运行良好,但是当我运行应用程序并使用下拉菜单选择类别“种族”时,尝试按种族绘制 BMI 失败。相反,我收到消息“错误:'x' 和 'units' 的长度必须 > 0”,这令人费解。 Stack Overflow 上具有类似错误消息的其他帖子建议将种族类别强制为小写,我尝试过(即 df$Race = tolower(df$Race),但这似乎没有帮助。

种族类别包括:

  • 白人或高加索人
  • 夏威夷原住民或其他太平洋岛民
  • 其他
  • 黑人或非裔美国人
  • 未知
  • 亚洲人
  • 患者拒绝
  • 美洲印第安人或阿拉斯加原住民

其中,我们的数据似乎仅包括 1 名自称为“美洲印第安人或阿拉斯加原住民”的患者。

您将在下面找到我为“app.R”编写的代码,以及我用来绘制数据的代码。

首先,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)

接下来,我们创建了 density.R,它包含两个函数 density_plot(),它为所有患者的 BMI 创建一个密度图,density_plots() 按特定类别创建一个 BMI 密度图。这第二个函数是我在 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)
}

【问题讨论】:

    标签: r ggplot2 shiny


    【解决方案1】:

    很难调试,因为它不可重现,但你可以试试这个:

      # 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)
      }
    

    【讨论】:

    • 感谢您的建议,mnist,以及在我不注意时可能发表过评论的任何其他人。我过滤了数据集以删除识别为“美洲原住民或阿拉斯加原住民”的单个患者,并且我的绘图能够正确渲染。密度图函数可能需要最少数量的数据点,而且无论如何,一个样本在任何情况下都不会产生非常丰富的图表。
    猜你喜欢
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    相关资源
    最近更新 更多