使用 Neo4j 图形数据构建应用程序时出现 R Shiny 反应式环境错误

R Shiny reactive environment error when building Apps using Neo4j graph data

提问人:MMAASS 提问时间:3/12/2019 更新时间:3/12/2019 访问量:440

问:

我正在使用 RNeo4j 包将 Neo4j 与 R 连接起来,使用 Neo4j 图形数据构建一个交互式 Shiny 应用程序。

该应用程序包含一个表格,显示了从 Neo4j 中提取的图形数据的属性,用户可以查看和更改表格内容(图形数据的属性)。 这些更改可以作为图形数据属性的更新写回 Neo4j。这个功能可以使用RNeo4j包中的&functiona来完成。updatePropgetOrCreateNode

但是,我有一个反应性错误。

以下是我的代码:

library(RNeo4j)
library(dplyr)
library(shiny)
library(shinydashboard)
library(visNetwork)
library(tidyr)
library(sqldf)
library(igraph)
library(plotly)
library(stringi)
library(stringr)

graph = startGraph("http://localhost:7474/db/data/", username = "xxx", password = "xxx")
summary(graph)

# build dashboard
# UI items list 
header <- dashboardHeader(
  title = "Neo4j"
)

sidebar <- dashboardSidebar(
  sidebarMenu (
  )
)

body <- dashboardBody(
  tabItems(
    tabItem(tabName = "dashboard1",
            box(textOutput("aa")),
            box(title = "CATEGORY", DT::dataTableOutput("category")),
            box(uiOutput("category_status"))

    )
  )
)

# UI
ui <- dashboardPage(header, sidebar, body)

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

  # Query graph data and properties from Neo4j and store them in table format in R 
  query = "
  MATCH (c:Category)
  RETURN c.id AS Category, c.Price AS Price, c.status AS Category_Status
  "
  info = cypher(graph, query) # R Table to store Neo4j data

  # Build Shiny output tables
  output$i1 <- renderTable(info)
  output$category = DT::renderDataTable(info, selection = 'single')
  # This is to build the function of change the status of category with 3 options
  output$category_status = renderUI({
    x = info[input$category_rows_selected, ]
    if (length(x)){
      selectInput("category_status", "", 
                  c( "Sold", "On Sale","Out of Stock"), 
                  selected = x$Category_Status)
    }
  })
  # Table to examine if the status change was made successfully
  output$aa<-renderText(input$category_status)

  # Write back the changes made in Shiny to Neo4j using "updateProp" & "getOrCreateNode" function in RNeo4j
  if(info$Category_Status[input$category_rows_selected] != input$category_status) {
    category_num = as.numeric(substring(info$Category[input$category_rows_selected], 16))
    updateProp(getOrCreateNode(graph, "Category", Category = paste("CC_CCAA_AAC.0C-", category_num, sep="")), 
               status = input$status)
  }
}

# Shiny dashboard
shiny::shinyApp(ui, server)

以下是错误消息:

Listening on http://127.0.0.1:4401
Warning: Error in .getReactiveEnvironment()$currentContext: Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
  55: stop
  54: .getReactiveEnvironment()$currentContext
  53: .subset2(x, "impl")$get
  52: $.reactivevalues
  50: server [#44]
Error in .getReactiveEnvironment()$currentContext() : 
  Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)

通过跟踪和错误,如果我删除将更改写回 Neo4j 的代码,Shiny 应用程序可以正常工作,这是代码的最后一部分。然而,这是这个项目的核心功能。

此外,这个回写功能通过单独站在 Shiny 之外正常工作。所以问题是 2 部分之间的相互作用。

我想知道我是否可以添加 Shiny 来解决这个问题。observeEvent

提前致谢。

闪亮 Rstudio R-NEO4J

评论


答:

1赞 thothal 3/12/2019 #1

正如您所说,代码的最后一部分导致了问题。背后的原因是你在这个代码块中使用。也就是说,您使用 ,并且没有固定值,但取决于您与应用程序的交互。reactivesinput$category_rows_selectedinput$category_statusinput$status

根据你想做什么,你基本上有2个选择:

  1. 将代码块包含在 中。但是,在这种情况下,当您更改相应的输入时,您的代码将永远不会更新。isolate
  2. 将代码块包含在 中。在这种情况下,每当任何一个输入(如上所列)更改其值时,都会执行此代码。如果希望代码块仅在某些输入发生更改时运行,则可以使用不想依赖的输入。observeisolate

例如,此代码将在 whenever 或 change 时执行,但如果 change 则不执行,因为它包含在 :input$category_rows_selectedinput$category_statusinput$statusisolate

observe({
   if(info$Category_Status[input$category_rows_selected] != input$category_status) {
       category_num = as.numeric(substring(info$Category[input$category_rows_selected], 16))
       updateProp(getOrCreateNode(graph, "Category", 
                  Category = paste("CC_CCAA_AAC.0C-", category_num, sep="")), 
                  status = isolate(input$status))
  }
})

评论

0赞 MMAASS 3/13/2019
谢谢thothal!我尝试按照您的描述使用观察函数,但是,我收到以下错误: 正在侦听 127.0.0.1:3918 警告:如果出现错误:参数长度为零 [没有可用的堆栈跟踪]
0赞 thothal 3/13/2019
很可能是因为 your 中的任何一个都在启动期间,并且您不能按 进行子集。简单的 qorkaround 将所有 youe 包裹起来,例如:input$NULLNULLinput$req()info$Category_Status[req(input$category_rows_selected)]