在 Shiny 中使用 if 条件循环语句编程反应式计数器

Programming a reactive counter with if conditional loop statement in Shiny

我一直在尝试用 Shiny 创建一个 dice/gambling 模拟器,但我遇到了两个问题(虽然这两个问题都可能与一个错误有关,但我不确定)。我基本上创建了一个 reactiveValue,最初在服务器内设置为 10000(美元),以及一个 sample() 函数,该函数仅从 1-6 之间绘制(对于六面骰子)并允许用户选择 dice/tosses。然后我设置了一个 observeEvent,其中一个 if 循环确定 sample() 函数中生成的随机数是否等于或大于用户下注的骰子数,并且只要 reactiveValue 保持大约1, 然后用户可以加倍 "money." 如果他们的赌注小于样本生成的赌注,那么他们输一半。如果他们输得太多以至于低于一,那么他们就不能再下注或至少被告知他们破产了,但这对代码来说并不是那么重要的部分。

现在,我似乎无法让 if 循环工作,因为它会抛出错误: 警告:if 错误:需要 TRUE/FALSE

的地方缺少值
 library(shiny)

 ui <- fluidPage(
  pageWithSidebar(
   titlePanel("Feelin' Lucky?"),

       sidebarPanel(
         p("In this simulation, you can select the number of dice you would like to roll,
           and then make a 'bet' on the numbers that will show up with every roll. If there are more faces 
           than the number you guessed, then you still win. If there are less faces, however, 
           you will lose 'money,' displayed at the top of the main panel. Give it a try and
           good luck!"),
        numericInput("dicenum", "Enter the number of dice to roll:", 1),
  numericInput("face", "What face do you think will be rolled?", 1),
  numericInput("bet", "How many of this face do you think will be rolled?", 1), 
  actionButton("go1", "GO!")
),
mainPanel(
  htmlOutput("the.dough"),
  htmlOutput("the.bet"),
  textOutput("results"),
  htmlOutput("results2"),
  htmlOutput("warning")
  )
 )
 )

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

    money <- 10000
    output$the.dough <- renderText(
    paste(money)
     )

   buttonValue <- reactiveValues(go1=FALSE)

   rv <- reactiveValues(money.tot = 10000)

   observeEvent(input$go1,{

isolate({buttonValue$go1=TRUE})
      the.roll <- sample(1:6, size = input$dicenum, replace=TRUE)
  the.face <- as.numeric(input$face) #Dice Face Bet
  amount <- as.numeric(input$bet)


output$warning <- renderText({

  goop <- sum(the.roll==the.face) 

  if ((goop >= amount) & (rv$money.tot>1)) {
    rv$money.tot <- sum(rv$money.tot, rv$money.tot*2-rv$money.tot)

    paste("Well-done! You won the bid! You now have: $", rv$money.tot)
  } else if ((goop < amount) & (rv$money.tot>1)) {
    rv$money.tot <- rv$money.tot-(rv$money.tot/2)
    paste("Darn! It looks like you lost the bid! You now have: $", rv$money.tot)
  } else if (rv$money.tot<1) {
    paste("You are broke! You cannot bid anymore money!")

  } else {
    NULL }
  })

  })
      }

          shinyApp(ui, server)

我已经查过这是什么意思,但我找不到一个案例可以准确解释为什么它在我的脚本中这样做,特别是因为 if 循环在作为基本 R if 循环编写时有效,即没有反应性或闪亮参与。工作循环示例:

  rvv <- 10000

  face.guess <- 4
   throw <- sample(1:6, size = 10, replace = TRUE)
    guess.howmany <- 2

   if (sum(throw==face.guess)>=guess.howmany & rvv>1) {
    rvv <- sum(rvv, rvv*2-rvv)

   print("Woohoo!") 
    print(rvv)
  } else if (sum(throw==face.guess)<guess.howmany & rvv>1){
   print("Darn")
    rvv <- rvv-(rvv/2)
  print(rvv)
   } else if (rvv<1) {
  print("You are broke! You can't bid anymore money!") }

其他时候,if 循环似乎确实部分起作用,但只是跳转到最后一个选项,以某种方式将起始 reactiveValue 降低到 1 以下并在第一次出价时宣布它们中断,这应该是不可能的。

我的电脑现在也很不稳定,所以如果上面有语法问题,我深表歉意 - 部分原因可能是目前无法正确 copy/paste。

非常感谢任何帮助!

编辑:固定代码。我还发现当用户获得正确的出价时,会有延迟,然后会抛出上述错误。当他们也猜测 high/wrong 时,它会显示最后一个选项 (print("You are broke!")),这似乎表明我调用其他条件 ("goop") 的方式存在明确问题.我只是不明白。

我找到了解决方法:我基本上必须在 renderText( ) 之外使用 if 循环,而是在 if 循环的每个步骤中嵌入多个呈现。我复制了下面更正的服务器部分。可能不是最优雅的修复,但它按我想要的方式工作:

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

   money <- 10000
   output$the.dough <- renderText(
    paste(money)
    )

  buttonValue <- reactiveValues(go1=FALSE)

  rv <- reactiveValues(money.tot = 10000)

  observeEvent(input$go1,{

    isolate({buttonValue$go1=TRUE})

    the.roll <- sample(1:6, size = input$dicenum, replace=TRUE)


    the.face <- as.numeric(input$face) #Dice Face Bet
    amount <- as.numeric(input$bet)
    goop <- sum(the.roll==the.face)

   if (isTRUE(goop >= amount) & isTRUE(rv$money.tot>1) & buttonValue$go1) {
      rv$money.tot <- sum(rv$money.tot, rv$money.tot*2-rv$money.tot)

      output$warning <- renderText({

       paste("Well-done! You won the bid! You now have: $", rv$money.tot)
        })
      } else if (isTRUE(goop < amount) & isTRUE(rv$money.tot>1) & buttonValue$go1) {
    rv$money.tot <- rv$money.tot-(rv$money.tot/2) 
    output$warning <- renderText({
    paste("Darn! It looks like you lost the bid! You now have: $", rv$money.tot)
    })

  } else if (isTRUE(rv$money.tot<1) & buttonValue$go1) {
    output$warning <- renderText({
    paste("You are broke! You cannot bid anymore money!")
    })
  } else {
    NULL }


output$results <- renderText(
  paste("You bid that there would be:", amount, "of the", the.face, "face.")

)
output$results2 <- renderText(
  paste("Actual Result:", as.numeric(sum(the.roll==the.face)), "of the", the.face)
)

  })

  }

希望这对正在尝试做类似事情的任何人有所帮助!