Shiny 将运行值保持在闪亮状态

Shiny 将运行值保持在闪亮状态,shiny,global-variables,reactive-programming,Shiny,Global Variables,Reactive Programming,我是一名环境科学家,试图为牡蛎创建一个收获模拟。我希望模拟显示两张地图,一张显示当前牡蛎数量,另一张显示禁止捕捞区(避难所)。单击地图上的某个绘图(每个绘图都有一个不可见的标记),应根据显示的地图进行不同的操作。单击牡蛎种群图应使种群更新为单击的地块中的牡蛎收获。单击保护区地图会导致单击的绘图更改为“打开”或“关闭” 据我所知,问题在于每次单击输入时,所有这些值都会重置。例如,无论之前显示的是哪张地图,“ShowSaccession”变量(本应显示F)是人口地图已启动,而T如果避难所地图已启动,

我是一名环境科学家,试图为牡蛎创建一个收获模拟。我希望模拟显示两张地图,一张显示当前牡蛎数量,另一张显示禁止捕捞区(避难所)。单击地图上的某个绘图(每个绘图都有一个不可见的标记),应根据显示的地图进行不同的操作。单击牡蛎种群图应使种群更新为单击的地块中的牡蛎收获。单击保护区地图会导致单击的绘图更改为“打开”或“关闭”

据我所知,问题在于每次单击输入时,所有这些值都会重置。例如,无论之前显示的是哪张地图,“ShowSaccession”变量(本应显示F)是人口地图已启动,而T如果避难所地图已启动,则每当单击新输入时,其起始值始终设置为False。牡蛎种群媒介和保护区媒介似乎做了同样的事情。如何防止这些变量重置回其起始值

另外,我对这个论坛还很陌生,我对礼仪不太清楚。我将在下面发布我所有的代码,而不包括我存储函数的两个脚本(我确信它们不是问题所在),但这是一个相当长的程序。这个问题与第70行和第152行之间的代码有关。我只会先发布这些行,下面是完整的脚本。如果这不是典型的礼节,请再次道歉

出现问题的行(位于服务器函数内部):

#生成反应值

offLim对于初学者,您没有正确使用
reactiveValues
。应该是这样的:

my_reactives <- reactiveValues()
my_reactives$offLim <- 0
my_reactives$showSanctuary <- F

my_reactives欢迎来到SO!正如您已经提到的,代码相当长(但我们仍然无法运行它,因为缺少一些函数)。因此,如果您尝试制作一个最小的可复制示例,您将得到更多帮助。尝试删除尽可能多的代码,这样最终你会有一个闪亮的应用程序运行并显示你的问题,但不会更多。可以使用一个小的示例数据集。谢谢,谢谢你教我网站礼仪。你的建议解决了这个问题!非常感谢你。
library(shiny)
library('leaflet')
library(raster)
library('sf')
library(rgdal)
source('updateFunctions.R')

effortLbl = "What is the maximum number of hours that you are willing to spend harvesting each day?"
amountLbl = "What is the maximum number of sacks of oysters you would harvest in one day?"
sizeLbl = "Select a minimum size for legal harvest (inches)"
shellLbl="Check to require culling on site"

ui<-fluidPage(
  numericInput(inputId="effort", label=effortLbl, value=8, min=1, max=16, step=1),
  numericInput(inputId="amount", label=amountLbl, value=4, min=1, max=40, step=1),
  numericInput(inputId="size", label=sizeLbl, value=3, min=1, max=6, step=1),
  checkboxInput(inputId="shell", label=shellLbl, value = FALSE),
  actionButton(inputId="update", label="Begin"),
  actionButton(inputId="sanctuaryMap", label="Set Sanctuaries"),
  actionButton(inputId="harvestMap", label="Choose Harvest Area"),
  leafletOutput("map"),
  textOutput("time"),
  textOutput("sacks"),
  textOutput("size")
)

server<-function(input, output, session){
  #Generate list of clickable coordinates
  cedKey <- readOGR(dsn=path.expand("shapefile"), layer="LC_10_Area") #Imports Cedar Key shape file
  ckCrd <- spTransform(cedKey, CRSobj = CRS("+init=epsg:4326")) #Converts shape file coordinate to longitude/latitude
  matCrd=expand.grid(x=seq(from=-83.1164,to=-83.06251,length.out=moveRow), #Generates a series of coordinates within range
                     y=seq(from=29.2169,to=29.26528,length.out=moveRow))
  df = data.frame(x = matCrd$x, y = matCrd$y)
  s = SpatialPixelsDataFrame(df[,c('x', 'y')], data = df, proj4string = crs(ckCrd))
  clp <- over(s[,c("x", "y")], ckCrd)
  cond <- !is.na(clp$Id)
  spNew<-s[cond,]
  spDf = as.data.frame(spNew)
  coord = data.frame(x=(trunc(df$x*1000)/1000), y=(trunc(df$y*1000)/1000))
  
  #Initialize oyster population variables
  nplts = 1600 #Total number of plots
  nsize = 7 #Number of size classes (including larva)
  oysters = matrix(0, nplts,nsize)
  myDens = vector(length=nplts) #Total number of oysters weighted by size
  myShell = vector(length=nplts) #The amount of dead shell (or other non-living hard substrate)
  myMaxDens = 1000 #The maximum capacity of every plot
  moveRow = sqrt(nplts) #The number of plots in a row
  
  #Initialize oyster population with randomization
  for(i in 1:nplts){
    initMin = c(20,20,5,5,0,0) #Minimum number of oysters of each size at game start
    initMax = c(60,40,30,20,10,5) #Maximum number of oysters of each size at game start
    oysters[i,1:6]=runif(6, initMin, initMax)
    oysters[i,7]=sum(oysters[i,1:6]*4)
  }
  oysters[!cond,]<-NA
  for(i in 1:nplts){
    myDens[i]=sum(oysters[i,1:6]*c(1:6))
    myShell[i]=0.2*myDens[i]
  }
  
  #Set values of outputs before initial update
  heatVec = vector(length=nplts)
  for(i in 1:nplts){
    heatVec[i] = (100*myDens[i])/myMaxDens
  }
  myMap = updateMap(heatVec)
  
  #Make Reactive Values
  offLim <- reactiveValues()
  offLim = 0
  
  showSanctuary <- reactiveValues()
  showSanctuary = F
  
  myOutputs <- reactiveValues()
  myOutputs$outHarvTime = 0
  myOutputs$outSacksTaken = 0
  myOutputs$outAvgSize = 0
  
  #React to click event
  observeEvent(input$map_marker_click, {
    click<-input$map_marker_click
    if(is.null(click))
      return()
    
    xClk=trunc(click$lng*1000)/1000
    yClk=trunc(click$lat*1000)/1000
    
    xCor = which(coord$x == xClk)
    yCor = which(coord$y == yClk)
    myPlot = intersect(xCor, yCor)
    
    if(showSanctuary == T){
      if(offLim[myPlot]==1){
        offLim[myPlot]=0
      }else if(offLim[myPlot]==0){
        offLim[myPlot]=1
      }
      myMap <- makeSanctuaryMap(offLim)
      myOutputs$finalMap = myMap
    }
    else{
      myHarvLim = input$amount
      myMaxTime = input$effort
      myMinSize = input$size
      returnShells = input$shell
      param = c(myHarvLim, myMaxTime, myMinSize, myPlot, returnShells)
    
      newOysters = oysters
      newDens = myDens
      newShell = myShell
    
      outVar<-localUpdate(param, newOysters, myMaxDens, newDens, newShell, nplts)
      oysters = outVar$oysters
      myDens = outVar$myDens
      myShell = outVar$myShell
    
      myOutputs$outAvgSize = outVar$avgSize
      myOutputs$outHarvTime = outVar$harvTime
      myOutputs$outSacksTaken = outVar$sacksTaken
      myOutputs$finalMap = outVar$myMap
    }
  })
  
  observeEvent(input$update,{
    #Make sanctuary variables. Needs to be reactive to be global
    showSanctuary = F #Whether the Map Currently Displays Sanctuary Areas
    offLim = vector(length=nplts) #1 if plot is a Sanctuary or 0 if not
    offLim[] = 0
    offLim[!cond]<-NA
    
    myOutputs$outAvgSize = NA
    myOutputs$outHarvTime = NA
    myOutputs$outSacksTaken = NA
    myOutputs$finalMap = myMap
  })
  
  observeEvent(input$sanctuaryMap,{
    print(showSanctuary)
    showSanctuary = T
    myMap <- makeSanctuaryMap(offLim)
    myOutputs$finalMap = myMap
  })
  
  observeEvent(input$harvestMap,{
    print(showSanctuary)
    showSanctuary = F
    myMap <- updateMap(heatVec)
    myOutputs$finalMap = myMap
  })
  
  localUpdate <- function(param, locOyster, myMaxDens, locDens, locShell, nplts){
    myUpdate<-updateFunction(locOyster, myMaxDens, locDens, locShell, param, nplts) #All updates done in separate script
    
    #Set oyster pop, dens, and dead shell according to updates
    oysters =  myUpdate$oysters
    for(i in 1:nplts){
      myDens[i] = sum(oysters[i,1:6]*c(1:6))
    }
    myShell = myUpdate$shell
    
    #Calculate heatmap values based on density (biomass)
    for(i in 1:nplts){
      heatVec[i] = (100*myDens[i])/myMaxDens
    }
    myMap <- updateMap(heatVec) #Create Map
    
    return(list(avgSize = myUpdate$avgSize, harvTime = myUpdate$harvTime, sacksTaken = myUpdate$sacksTaken, 
                myMap = myMap, myShell = myShell, myDens = myDens, oysters = oysters))
  }
  
  #Assemble and Display Outputs
  output$map <- renderLeaflet({
    input$map_marker_click #Makes output dependent on map or button click (via isolate)
    input$sanctuaryMap
    input$harvestMap
    input$update
    isolate(myOutputs$finalMap)})
  output$time <- renderText({
    input$map_marker_click
    input$update
    timeString <- isolate(c("Time Spent Harvesting Each Day: ", 
                            toString(trunc(myOutputs$outHarvTime*100)/100), " hours"))
    timeString})
  output$sacks <- renderText({
    input$map_marker_click
    input$update
    sacksString<-isolate(c("Average Number of Sacks Harvested per Day: ", 
                           toString(trunc(myOutputs$outSacksTaken*100)/100), " sacks"))
    sacksString})
  output$size <- renderText({
    input$map_marker_click
    input$update
    sizeString<-isolate(c("Average Size of Harvested Oysters this Year: ", 
      toString(trunc(myOutputs$outAvgSize*100)/100), " inches"))
    sizeString})
}

shinyApp(ui = ui, server = server)
my_reactives <- reactiveValues()
my_reactives$offLim <- 0
my_reactives$showSanctuary <- F