R Markdown无法同时编译HTML与运行Shiny代码求助
解决R Markdown编译HTML与Shiny运行冲突的问题
你的核心问题是**runtime: shiny的存在导致文档类型冲突**:当yaml中包含runtime: shiny时,文档是交互式Shiny文档,只能编译成带Shiny交互的HTML,无法作为普通静态HTML编译;去掉runtime: shiny后,普通HTML文档不支持Shiny的运行上下文,直接调用shinyApp()会报错。
下面提供两种针对性解决方案:
方案1:制作可编译的交互式Shiny文档(推荐,同时满足交互+HTML输出)
保留runtime: shiny,但移除代码中的shinyApp(ui = ui, server = server)调用——因为启用runtime: shiny的R Markdown文档会自动识别并运行UI和server逻辑,无需手动启动Shiny应用。
修改后的完整代码:
--- title: "Report" author: "Name" date: "`r Sys.Date()`" output: html_document: df_print: paged runtime: shiny # 保留这一行,启用Shiny交互 editor_options: markdown: wrap: 72 ---
knitr::opts_chunk$set(echo = TRUE) library(shiny) library(leaflet) library(rgdal) library(sf) library(dplyr) library(RColorBrewer) library(htmlwidgets)
Summary
Text
Section
Text
wave_data <- read_sf("~/path/Wave_data_32631.geojson") wave_data <- st_transform(wave_data, crs = '+proj=longlat +datum=WGS84') wave_data2 <- wave_data %>% mutate_at(vars(An_mn_P_OD), ~ as.integer(round(.x))) bins <- c(0, 25, 50, 100, 150, 200, 300, 400, 500, 1000, 3100) pal <- colorBin("RdYlBu", domain = wave_data2$Ave_Depth, bins = bins) # 直接定义UI,无需包裹在shinyApp中 bootstrapPage( tags$style(type = "text/css", "html, body {width:100%;height:100%}"), leafletOutput("wave_data_map", width = "100%", height = "100%"), absolutePanel(top = 10, right = 10, sliderInput("wave_data_range", "Wave energy", min = 0, max = 75, value = c(min(wave_data2$An_mn_P_OD), max(wave_data2$An_mn_P_OD)), step = 5, round = 0.5, dragRange = TRUE) ) ) # 直接定义server逻辑,无需手动调用shinyApp server <- function(input, output, session) { wave_energy_output <- reactive({ wave_data2 %>% filter(An_mn_P_OD >= input$wave_data_range[1], An_mn_P_OD <= input$wave_data_range[2]) # 移除无用的group_by(Lat),否则会保留分组导致leaflet数据处理异常 }) output$wave_data_map <- renderLeaflet({ leaflet() %>% addProviderTiles(providers$Esri.WorldTopoMap) %>% setView(lng = -4.2026458, lat = 56.4906712, zoom = 5) %>% addPolygons(data = wave_data2, weight = 1, smoothFactor = 0.5, color = "white", fillOpacity = 0.3, fillColor = pal(wave_data2$Ave_Depth)) %>% addLegend(pal = pal, values = wave_data2$Ave_Depth, title = "Average depth", labFormat = labelFormat(suffix = "m"), opacity = 0.7, position = "bottomright") }) observeEvent(input$wave_data_range, { data <- wave_energy_output() leafletProxy("wave_data_map", data = data) %>% clearShapes() %>% addPolygons(data = data, fillColor = pal(data$Ave_Depth), # 这里改为data$Ave_Depth,避免依赖reactive重复调用 weight = 1, smoothFactor = 0.5, color = "white", fillOpacity = 0.5) }) }
Section
Section
编译后会生成**带交互功能的HTML文档**,既能正常显示静态文本,也能使用Shiny滑块交互地图。 --- ## 方案2:制作普通静态HTML文档+可单独运行的Shiny代码 如果需要纯静态HTML文档,同时保留可单独运行的Shiny代码,只需移除yaml中的`runtime: shiny`,并将Shiny代码块设置为`eval=FALSE`(编译时不执行代码,仅显示代码内容),用户可复制代码到R环境单独运行。 ### 修改后的yaml部分: ```yaml --- title: "Report" author: "Name" date: "`r Sys.Date()`" output: html_document: df_print: paged # 移除runtime: shiny editor_options: markdown: wrap: 72 ---
修改后的Shiny代码块:
# 这里保留你原有的完整Shiny代码(包含shinyApp调用) wave_data <- read_sf("~/path/Wave_data_32631.geojson") wave_data <- st_transform(wave_data, crs = '+proj=longlat +datum=WGS84') wave_data2 <- wave_data %>% mutate_at(vars(An_mn_P_OD), ~ as.integer(round(.x))) bins <- c(0, 25, 50, 100, 150, 200, 300, 400, 500, 1000, 3100) pal <- colorBin("RdYlBu", domain = wave_data2$Ave_Depth, bins = bins) # Define UI for application ui <- bootstrapPage( tags$style(type = "text/css", "html, body {width:100%;height:100%}"), leafletOutput("wave_data_map", width = "100%", height = "100%"), absolutePanel(top = 10, right = 10, sliderInput("wave_data_range", "Wave energy", min = 0, max = 75, value = c(min(wave_data2$An_mn_P_OD), max(wave_data2$An_mn_P_OD)), step = 5, round = 0.5, dragRange = TRUE) ) ) # Define server logic server <- function(input, output, session) { wave_energy_output <- reactive({ data <- wave_data2 %>% filter(An_mn_P_OD >= input$wave_data_range[1], An_mn_P_OD <= input$wave_data_range[2]) data %>% group_by(Lat) }) output$wave_data_map <- renderLeaflet({ leaflet() %>% addProviderTiles(providers$Esri.WorldTopoMap) %>% setView(lng = -4.2026458, lat = 56.4906712, zoom = 5) %>% addPolygons(data = wave_data2, weight = 1, smoothFactor = 0.5, color = "white", fillOpacity = 0.3, fillColor = pal(wave_data2$Ave_Depth)) %>% addLegend(pal = pal, values = wave_data2$Ave_Depth, title = "Average depth", labFormat = labelFormat (suffix = "m"), opacity = 0.7, position = "bottomright") }) observeEvent(input$wave_data_range, { data <- wave_energy_output() leafletProxy("wave_data_map", data = data) %>% clearShapes() %>% addPolygons(data = data, fillColor = pal(wave_energy_output()$Ave_Depth), weight = 1, smoothFactor = 0.5, color = "white", fillOpacity = 0.5) }) } # Run the application shinyApp(ui = ui, server = server)
编译后得到静态HTML文档,Shiny代码会以代码块形式展示,用户可复制到R中单独运行Shiny应用。
内容的提问来源于stack exchange,提问作者AlexaQuinoa
相关产品推荐
相关产品推荐

