R 闪亮的应用程序用于显示绘图和表格数据

问题描述 投票:0回答:1

我完全不知道如何构建一个显示图形和表格数据的 R Shiny 应用程序。目标是 1. 废弃 USGS 数据,2. 构建流量数据的绘图面板,3. 拥有一个包含数据表的选项卡。下面是抓取 USGS 数据并成功构建绘图面板的工作脚本。我需要将表格和绘图的数据框架开发(相同的数据,只是以不同的方式显示)移至绘图构建服务器循环之外的反应函数,但我一直无法弄清楚。

library(shiny)
library(shinythemes)
library(dplyr)
library(dataRetrieval)
library(plotly)
library(lubridate)
library(DT)

C_site_numbers <- list("10308200", "10309000")
C_site_names <- list("Markleeville (cfs)", "Gardnerville (cfs)")

ui <- fluidPage(theme = shinytheme("yeti"),
                titlePanel("USGS Streamflow Data"),
                
                fluidRow(
                  column(4,
                         wellPanel(dateInput("start_date", "Start Date:", value = Sys.Date() - 7), width = 10)),
                  column(4, 
                         wellPanel(dateInput("end_date", "End Date:", value = Sys.Date()), width = 10)),
                  mainPanel(
                    tabsetPanel(
                      tabPanel("Carson Basin", plotlyOutput("C_plot_panel", width = "100%", height = ceiling(length(C_site_numbers)) * 400)),
                      tabPanel("Carson Tablular", dataTableOutput("Data_Tables", width = "100%", height = ceiling(length(C_site_numbers)) * 400))
                    )
                  )
                ))

server <- function(input, output) {
  
  # Define a reactive expression for the data frame
  df <- reactive({
    start_date <- ymd(input$start_date)
    end_date <- ymd(input$end_date)
    
    df <- data.frame(seq(from = start_date, to = end_date, by = 0.0069444444444444))  ##by value is equal to 5 mins intervals
    colnames(df)[1] <- 'dateTime'
    
    # Loop through each site number and download/streamflow data
    for (C_site_number in C_site_numbers) {
      n <- which(C_site_numbers == C_site_number)
      plot_n <- unlist(C_site_names[n])
      para_code = if (plot_n == 'Lahontan (acre-ft)') {'00054'} else {'00060'}
      streamflow <- readNWISuv(siteNumbers = C_site_number, parameterCd = para_code, 
                               startDate = start_date, endDate = end_date)
      attr(streamflow$dateTime, 'tzone') <- "America/Los_Angeles"
      
      # Prepare data for merging
      streamflow_df <- data.frame(
        dateTime = as.POSIXct(streamflow$dateTime, format = "%Y-%m-%d %H:%M"),
        Flow = if (plot_n == 'Lahontan (acre-ft)') {streamflow$X_00054_00000} else {streamflow$X_00060_00000}
      )
      
      # Merge data frames
      df <- merge(x = df, y = streamflow_df, by = 'dateTime', all.x = TRUE, all.y = FALSE)
    }
    
    df
  })
  
  # Carson Plot Panel
  output$C_plot_panel <- renderPlotly({
    # Create an empty list to store the individual plots
    C_plots <- list()
    
    # Loop through each site number and download/streamflow data
    for (C_site_number in C_site_numbers) {
      n <- which(C_site_numbers == C_site_number)
      plot_n <- unlist(C_site_names[n])
      streamflow_df <- df()
      
      # Create the plot using plotly
      plot <- plot_ly(data = streamflow_df, x = ~dateTime, y = ~Flow, type = "scatter", mode = "lines") %>%
        layout(yaxis = list(title = plot_n)) %>%
        layout(hovermode = "x unified", plot_bgcolor = 'rgb(212,213,214)', showlegend = FALSE)
      C_plots[[C_site_number]] <- plot
    }
    
    C_plot_panel <- subplot(C_plots, nrows = ceiling(length(C_site_numbers)), titleY = TRUE, margin = 0.07)
  })
  
  # Carson Tabular
  output$Data_Tables <- renderDataTable({
    streamflow_df <- df()
    streamflow_df
  })
}

shinyApp(ui = ui, server = server)

提前非常感谢!在询问之前我已经尝试了所有资源(深入的SO搜索者、chatGPT、朋友)。自学 R Shiny 并不容易。

r shiny plotly subplot dt
1个回答
0
投票

一种方法是

library(shiny)
library(shinythemes)
library(dplyr)
library(dataRetrieval)
library(plotly)
library(lubridate)
library(DT)

C_site_numbers <- list("10308200", "10309000")
C_site_names <- list("Markleeville (cfs)", "Gardnerville (cfs)")

ui <- fluidPage(theme = shinytheme("yeti"),
                titlePanel("USGS Streamflow Data"),
                
                fluidRow(
                  column(4,
                         wellPanel(dateInput("start_date", "Start Date:", value = Sys.Date() - 7), width = 10)),
                  column(4, 
                         wellPanel(dateInput("end_date", "End Date:", value = Sys.Date()), width = 10)),
                  mainPanel(
                    tabsetPanel(
                      tabPanel("Carson Basin", plotlyOutput("C_plot_panel", width = "100%", height = ceiling(length(C_site_numbers)) * 400)),
                      tabPanel("Carson Tablular", dataTableOutput("Data_Tables", width = "100%", height = ceiling(length(C_site_numbers)) * 400))
                    )
                  )
                ))

server <- function(input, output) {
  
  # Define a reactive expression for the data frame & plots
  df <- reactive({
    start_date <- ymd(input$start_date)
    end_date <- ymd(input$end_date)
    dateTime=format( seq.POSIXt(as.POSIXct(start_date), as.POSIXct(end_date), by = "5 min"),
                     "%Y-%m-%d %H:%M", tz="America/Los_Angeles")   ## 
    df <- data.frame(dateTime=as.POSIXct(dateTime))
    # Create an empty list to store the individual plots
    
    # df <- data.frame(seq(from = start_date, to = end_date, by = 0.0069444444444444))  ##by value is equal to 5 mins intervals
    # colnames(df)[1] <- 'dateTime'
    df1 <- data.frame(dateTime=as.POSIXct(start_date), Flow=NA, site=1)
    for (C_site_number in C_site_numbers) {
      n <- which(C_site_numbers == C_site_number)
      plot_n <- unlist(C_site_names[n])
      para_code = if (plot_n == 'Lahontan (acre-ft)') {'00054'} else {'00060'}
      streamflow <- readNWISuv(siteNumbers = C_site_number, parameterCd = para_code, 
                               startDate = start_date, endDate = end_date)
      attr(streamflow$dateTime, 'tzone') <- "America/Los_Angeles"
      
      # Prepare data for merging
      streamflow_df <- data.frame( # site = C_site_names[n], 
        dateTime = as.POSIXct(streamflow$dateTime, format = "%Y-%m-%d %H:%M"),
        Flow = if (plot_n == 'Lahontan (acre-ft)') {streamflow$X_00054_00000} else {streamflow$X_00060_00000},
        site = n
      )
      print(n)
      # Merge data frames
      dfa <- merge(x = df, y = streamflow_df, by = 'dateTime', all.x = TRUE, all.y = FALSE)
      df1 <- rbind(df1,dfa)
    }
    df2 <- df1[complete.cases(df1),]  ## remove NAs for Flow
    
    C_plots <- list()
    # Loop through each site number and download/streamflow data
    lapply(C_site_numbers, function(C_site_number){
      n <- which(C_site_numbers == C_site_number)
      plot_n <- unlist(C_site_names[n])

      # Create the plot using plotly
      plot <- plot_ly(data = df2[df2$site==n,], x = ~dateTime, y = ~Flow, type = "scatter", mode = "lines") %>%
        layout(yaxis = list(title = plot_n)) %>%
        layout(hovermode = "x unified", plot_bgcolor = 'rgb(212,213,214)', showlegend = FALSE)
      C_plots[[C_site_number]] <<- plot
    
    })
    
    return(list(data = df2, plots = C_plots))
  })
  
  # Carson Plot Panel
  output$C_plot_panel <- renderPlotly({
    C_plots <- df()[[2]]
    C_plot_panel <- subplot(C_plots, nrows = ceiling(length(C_site_numbers)), titleY = TRUE, margin = 0.07)
  })
  
  # Carson Tabular
  output$Data_Tables <- renderDataTable({
    mydf <- df()[[1]]
    mydf %>% select(-site)
  })
}

shinyApp(ui = ui, server = server)
© www.soinside.com 2019 - 2024. All rights reserved.