使用R Shiny应用创建框线图时出现问题

时间:2019-11-15 15:41:29

标签: r shiny statistics visualization boxplot

我对Shiny R应用程序非常陌生。我正在尝试在Shiny R应用程序中对某些数据集进行简单的箱形图绘制。

在这里,我正在文件df.csv中显示一些示例数据。数据如下所示。显示以下数据的dput

structure(list(Samples = structure(1:10, .Label = c("Sample1", 
"Sample10", "Sample2", "Sample3", "Sample4", "Sample5", "Sample6", 
"Sample7", "Sample8", "Sample9"), class = "factor"), Type = structure(c(2L, 
1L, 2L, 2L, 2L, 1L, 2L, 2L, 1L, 1L), .Label = c("Normal", "Tumor"
), class = "factor"), A1BG = c(0, 0.01869105, 0.026705782, 0.016576987, 
0, 0.007636787, 0.015756547, 0.00609601, 0.115575528, 0.04717536
), A1BG.AS1 = c(0, 0.096652515, 0.086710002, 0.04683499, 0.188283185, 
0.104318353, 0.102735593, 0.100064808, 0.04717536, 0.159745808
), A1CF = c(1.616942802, 1.367084444, 1.101855892, 1.3823884, 
0.631627098, 2.407159505, 1.687449785, 1.229844138, 0.87989414, 
0.642785868), A2M = c(3.357654845, 3.149165846, 3.654774122, 
2.851143092, 2.952601867, 4.002335454, 4.123949457, 3.691343955, 
3.553064673, 3.425443559), A2M.AS1 = c(0.217308191, 0.08268571, 
0.297320544, 0.101579093, 0.020102613, 0.35578965, 0.288014115, 
0.145352771, 0.043808388, 0.104677012), A2ML1 = c(0, 0.017949113, 
0.00984907, 0.002289616, 0, 0.002100359, 0.032146138, 0.052275569, 
0.537892142, 0), A2ML1.AS1 = c(0.631627098, 0.04717536, 1.229844138, 
0, 4.002335454, 0, 1.229844138, 1.229844138, 0.04717536, 0)), row.names = c(NA, 
-10L), class = "data.frame")

利用以上信息,我正在尝试制作一个闪亮的应用程序。我的代码如下所示:

library(shiny)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("thegene", "Gene", choices = c("A2M", "A1CF", "A2MP1"), selected = "A2M"),
      radioButtons("colour","Colour of histogram",choices=c("red","green","blue"),selected="red"),
      width = 3
    ),
    mainPanel(
      plotOutput("boxplot"),
      width = 9
    )
  )
)

server <- function(input, output) {

  df <- read.csv("df.csv")

  library(reshape2)
  library(ggplot2)
  library(ggpubr)
  library(EnvStats)

  df.m <- melt(df, c("Samples", "Type"))

  output$boxplot <- renderPlot({
    ggplot(data=df.m, aes(x = Type, y = value, fill=variable)) +
      geom_boxplot() +
      theme_bw(base_size = 14) + xlab("") + ylab("Expression logFPKM") +
      theme(axis.text=element_text(size=15, face = "bold", color = "black"),
            axis.title=element_text(size=15, face = "bold", color = "black"),
            strip.text = element_text(size=15, face = "bold", color = "black")) +
      stat_compare_means(method = "t.test", size=5) + stat_n_text()
  })

}

# Run the application 
shinyApp(ui = ui, server = server)

因此,我重塑了信息,然后尝试制作一个应用程序,为肿瘤(6个样本)和正常(4个样本)之间的每个基因创建一个箱线图。

我没有看到任何错误,但是我也没有得到期望的结果。我上面的代码的输出如下所示:

enter image description here

1)每种类型下方的方框图中的样本数量错误。

2)对于基因选择,我只能看到三个基因。我在那里看不到其他基因。如何检查其他基因?

3)直方图的颜色也不起作用。

感谢您的帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

尝试一下。

我做了一些更改,您可以保留一些并撤消其他更改。

  1. 我没有ggpubrEnvStats,所以我删除了一些绘图摘要。
  2. 我已定义了静态数据,您应该返回到read.csv解决方案。
  3. 我在服务器声明中添加了session,这是您要以编程方式更新任何输入所必需的。
  4. 我有一个效率低下的反应式块,它只返回所有原始数据;从目前的情况来看,这是反习惯用语,但是仅在演示/当源数据发生更改时添加了updateSelectInput才被使用。仅当您的数据动态更改(例如,用户上传数据或数据库查询)时,才需要这样做,否则alldat()实际上应该只是df.m(并且您的输入应静态定义)。
  5. 我更新了彩色单选按钮的用法。
library(shiny)
library(reshape2)
library(ggplot2)
library(ggpubr)
library(EnvStats)

df <- structure(list(Samples = structure(1:10, .Label = c("Sample1", 
"Sample10", "Sample2", "Sample3", "Sample4", "Sample5", "Sample6", 
"Sample7", "Sample8", "Sample9"), class = "factor"), Type = structure(c(2L, 
1L, 2L, 2L, 2L, 1L, 2L, 2L, 1L, 1L), .Label = c("Normal", "Tumor"
), class = "factor"), A1BG = c(0, 0.01869105, 0.026705782, 0.016576987, 
0, 0.007636787, 0.015756547, 0.00609601, 0.115575528, 0.04717536
), A1BG.AS1 = c(0, 0.096652515, 0.086710002, 0.04683499, 0.188283185, 
0.104318353, 0.102735593, 0.100064808, 0.04717536, 0.159745808
), A1CF = c(1.616942802, 1.367084444, 1.101855892, 1.3823884, 
0.631627098, 2.407159505, 1.687449785, 1.229844138, 0.87989414, 
0.642785868), A2M = c(3.357654845, 3.149165846, 3.654774122, 
2.851143092, 2.952601867, 4.002335454, 4.123949457, 3.691343955, 
3.553064673, 3.425443559), A2M.AS1 = c(0.217308191, 0.08268571, 
0.297320544, 0.101579093, 0.020102613, 0.35578965, 0.288014115, 
0.145352771, 0.043808388, 0.104677012), A2ML1 = c(0, 0.017949113, 
0.00984907, 0.002289616, 0, 0.002100359, 0.032146138, 0.052275569, 
0.537892142, 0), A2ML1.AS1 = c(0.631627098, 0.04717536, 1.229844138, 
0, 4.002335454, 0, 1.229844138, 1.229844138, 0.04717536, 0)), row.names = c(NA, 
-10L), class = "data.frame")
df.m <- reshape2::melt(df, c("Samples", "Type"))

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("thegene", "Gene", choices = c("A2M", "A1CF", "A2MP1"), selected = "A2M"),
      radioButtons("colour","Colour of histogram",choices=c("red","green","blue"),selected="red"),
      width = 3
    ),
    mainPanel(
      plotOutput("boxplot"),
      width = 9
    )
  )
)

server <- function(input, output, session) {

  alldat <- reactive({
    # this is not an efficient use of a reactive block: since it does
    # not depend on any dynamic data, it will fire only once, so if
    # your data is static then this might be a touch overkill ... but
    # the premise is that your `df.m` is data that can change based on
    # updating it (e.g., DB query) or user-uploaded data (e.g., CSV
    # upload)
    choices <- unique(df.m$variable)
    selected <- isolate(input$thegene)
    if (!selected %in% choices) selected <- choices[1]
    updateSelectInput(session, "thegene", choices = choices, selected = selected)
    df.m
  })

  dat <- reactive({
    x <- alldat()
    x[ x$variable == input$thegene,,drop=FALSE]
  })

  output$boxplot <- renderPlot({
    ggplot(data = dat(), aes(x = Type, y = value, fill = variable)) +
      geom_boxplot() +
      theme_bw(base_size = 14) + xlab("") + ylab("Expression logFPKM") +
      theme(axis.text=element_text(size=15, face = "bold", color = "black"),
            axis.title=element_text(size=15, face = "bold", color = "black"),
            strip.text = element_text(size=15, face = "bold", color = "black")) +
      scale_fill_manual(values = input$colour)
  })

}

# Run the application 
shinyApp(ui = ui, server = server)

一些注释/意见

  • 当由于过滤或用户提供的修饰符而产生动态数据时,我发现有一个反应性块可以进行 just 过滤/修改,这很好,因此可以将修改后的数据用于多个从属反应块,请依我的dat <- reactive(...)
  • 更重要的是,我发现许多不太出色的闪亮应用程序尝试在单个反应块中做太多事情;当我看到很多事情发生时,我倾向于认为(a)将反应块分成较小的块,尤其是当代码在多个块中重复时;和/或(b)编写可完成大部分工作的外部函数,以使闪亮的应用程序本身看起来更紧凑。声明性函数名称可以使可读性/可维护性更加容易(并且可以进行单元测试!)。
  • 为此添加了任何保护措施;一种保护措施(尽管此应用程序不会立即显示它)是使用req()来确保输入在启动过程中已“稳定”。对于较大的应用程序,可能会注意到在input$thegene具有有效值之前会触发一些反应块,这可能会导致某些绘图/表格闪烁。
  • 当有一个选择输入将很快被覆盖/更新时,我通常会选择choices="(initializing)"之类的东西。在这种情况下,只要合理的默认选择很有可能,只要这些选择很有可能或确定会出现在真实数据中即可。