R Shiny: 无限递归

3
我正在开发一个Shiny应用程序,旨在猜测用户输入文本片段中的下一个单词。为此,我加载了三个包含可能的下一个单词猜测的数据框,并使用grepl查找与用户输入文本末尾匹配的三元组或二元组。在“常规”R中构建时没有出现错误或问题,但在转换为Shiny时,我遇到了以下错误:
错误:嵌套评估太深:无限递归/选项(表达式=)?
正如其他Stack Overflow帖子所建议的那样,我调整了options(expressions = )值,但仍然遇到错误。没有太多其他信息来指导我,并且注意到它已经没有问题,有人能看出我哪里错了吗?提前感谢!
背景资料:Win 7,64位操作系统|R v3.1.1|RStudio v0.98.944 ui.R
library(shiny)
shinyUI(fluidPage(
   titlePanel("Capstone: Word Guesser"),
      fluidRow(
         column(12, 
            mainPanel(
               h4('Sentence Fragment'),
               p('Please enter a snippet of text - with this as a start, the app will provide you 5 guesses in ranked order to complete your phrase'),
               textInput('sentence', "Snippet:", value = "Enter some text and have a great"),
               h4('Guesses'),
               p('Below are our top five guesses for the word that completes this snippet'),
               verbatimTextOutput("final.guesses")
            )
         )
      )
))

server.R

options(expressions = 10000)
quad.grams <- readRDS("quadgrams.rds")
tri.grams <- readRDS("trigrams.rds")
kneser.ney <- readRDS("kneserney.rds")
library(shiny)
library(tm)
library(plyr)
library(stringi)
library(RWeka)
library(stringr)
function(input, output, clientData, session) {
   observe({
      sentence <- reactive({as.character(input$sentence)})
      sentence <- reactive({str_replace_all(sentence(), "[[:punct:]]", "")})
      sentence <- reactive({tolower(sentence())})
      sentence <- reactive({scan_tokenizer(sentence())})
      n <- reactive({length(sentence())})
      tri.frag <- reactive({paste(sentence()[n() - 2], sentence()[n() - 1], sentence()[n()])})
      bi.frag <- reactive({paste(sentence()[n() - 1], sentence()[n()])})
      quad.guesses <- reactive({quad.grams[grepl(tri.frag(), quad.grams$n1.Gram) == TRUE, 2]})
      tri.guesses <- reactive({tri.grams[grepl(bi.frag(), tri.grams$n1.Gram) == TRUE, 2]})
      guesses <- reactive({c(quad.guesses(), tri.guesses(), kneser.ney$nGram)})
      output$final.guesses <- renderPrint({guesses()[1:5]})
   })
}
2个回答

5
我认为你的问题在这里(无法测试以确保):
observe({
  sentence <- reactive({as.character(input$sentence)})
  sentence <- reactive({str_replace_all(sentence(), "[[:punct:]]", "")})
  sentence <- reactive({tolower(sentence())})
  sentence <- reactive({scan_tokenizer(sentence())})

以下四行代码都是让sentence具有响应性,每一行都依赖于自己、input$sentence和其他三行,这会导致shiny混乱不堪。更好的解决方案是:

observe({
  sentence1 <- reactive({as.character(input$sentence)})
  sentence2 <- reactive({str_replace_all(sentence1(), "[[:punct:]]", "")})
  sentence3 <- reactive({tolower(sentence2())})
  sentence4 <- reactive({scan_tokenizer(sentence3())})

您可以尝试删除sentence1这行代码,因为我认为input$sentence已经是字符格式了。如果您喜欢的话,可以将剩余的代码合并在一起,如下所示:

  sentence <- reactive({scan_tokenizer( tolower(
                str_replace_all(input$sentence, "[[:punct:]]", "") ))
             })

再次感谢您解答我的Shiny问题 - 几个月前您曾经帮助过我,我非常感激。我一直在尝试调整它,今天早上得出了相同的结论。不过,我会采纳您的建议并简化处理步骤。 - Ryan S

2

冒着引起另一个无限循环的风险,我很高兴地说我能够发布自己的答案。问题似乎是“sentence”变量的重复使用。我猜当使用响应式时,即使您只是转换它们,也不能反复重用变量。不管怎样,现在这段代码可以正常工作了:

server.R

options(shiny.maxRequestSize = 50*1024^2)
options(expressions = 10000)
quad.grams <- readRDS("quadgrams.rds")
tri.grams <- readRDS("trigrams.rds")
kneser.ney <- readRDS("kneserney.rds")
library(shiny)
library(tm)
library(plyr)
library(stringi)
library(RWeka)
library(stringr)
function(input, output, clientData, session) {
      snippet <- reactive({as.character(input$sentence)})
      clean.snippet <- reactive({str_replace_all(snippet(), "[[:punct:]]", "")})
      lower.snippet <- reactive({tolower(clean.snippet())})
      tokens <- reactive({scan_tokenizer(lower.snippet())})
      n <- reactive({length(tokens())})
      tri.frag <- reactive({paste(tokens()[n() - 2], tokens()[n() - 1], tokens()[n()])})
      bi.frag <- reactive({paste(tokens()[n() - 1], tokens()[n()])})
      quad.guesses <- reactive({quad.grams[grepl(tri.frag(), quad.grams$n1.Gram) == TRUE, 2]})
      tri.guesses <- reactive({tri.grams[grepl(bi.frag(), tri.grams$n1.Gram) == TRUE, 2]})
      guesses <- reactive({c(quad.guesses(), tri.guesses(), kneser.ney$nGram)})
      output$final.guesses <- renderPrint({guesses()[1:5]})
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接