使用R Shiny中的反应式’value’来更新自身

huangapple go评论71阅读模式
英文:

Updating a reactive 'value' using itself in R Shiny

问题

我正在尝试构建一个仪表板,以跟踪我在Bugzilla中的团队错误。检索数据的查询速度较慢,因此我希望只检索已更改的错误并更新本地副本。

我有一个名为'get_bugzilla'的函数,它返回所有内容,或者如果提供了时间戳,则返回该时间戳之后的所有已更改内容。

我当前的最佳尝试是以响应式方式使用它:

poll<-reactiveTimer(intervalMs = 10000)
ckbdata<-reactive({get_bugzilla()})
ckbdata<-reactive({
poll()
wip<-ckbdata()
new<-get_bugzilla(max(wip[['last_change_time']]))
if(length(new)>0){
wip<-wip[!(id %in% new[['id']]),]
wip<-rbind(wip,new)
}
wip
})


这导致错误"evaluation nested too deeply: infinite recursion / options(expressions=)?",这是我担心的问题。但我无法找出正确的解决方法。
英文:

I am trying to build a dashboard to keep track of my groups bugs in bugzilla. The query to retrieve this data is slow, so I would like to only retrieve changed bugs and update a local copy.

I have a function 'get_bugzilla' which returns everything, or if provided a timestamp, everything changed after that timestamp.

My current best attempt to use this in a reactive fashion is:

poll&lt;-reactiveTimer(intervalMs = 10000)
ckbdata&lt;-reactive({get_bugzilla()})
ckbdata&lt;-reactive({
	poll()
	wip&lt;-ckbdata()
	new&lt;-get_bugzilla(max(wip[[&#39;last_change_time&#39;]]))
	if(length(new)&gt;0){
		wip&lt;-wip[!(id %in% new[[&#39;id&#39;]]),]
		wip&lt;-rbind(wip,new)
	}
	wip
})

This is producing the error "evaluation nested too deeply: infinite recursion / options(expressions=)?", which was something I was worried about. But I cannot work out the correct way of doing this.

答案1

得分: 0

这是因为存在无限循环,即一个响应式表达式在调用另一个响应式表达式,反之亦然。 ckbdata 被定义为一个响应式表达式两次,这很可能导致无限递归。

也许这个方法可行:

poll <- reactiveTimer(intervalMs = 10000)

ckbdata <- reactive({
  poll()
  current_data <- isolate(ckbdata())
  # 如果当前数据为空,获取所有数据
  if (is.null(current_data)) {
    get_bugzilla()
  } else {
    get_bugzilla(max(current_data[['last_change_time']])
  }
})

ckbdata_updated <- reactive({
  current_data <- ckbdata()
  # 如果有修改或 bug,则更新本地副本
  new_data <- get_bugzilla(max(current_data[['last_change_time']])
  if (length(new_data) > 0) {
    current_data <- current_data[!(current_data$id %in% new_data[['id']]),]
    current_data <- rbind(current_data, new_data)
  }
  current_data
})

祝一切顺利!

英文:

This is because there is an infinite loop i.e. one of the reactive expression is calling another and vice versa. ckbdata is defined as a reactive expression twice, which is likely causing the infinite recursion.

Maybe this works

poll &lt;- reactiveTimer(intervalMs = 10000)

ckbdata &lt;- reactive()
  poll()
  current_data &lt;- isolate(ckbdata())
  # retrieve all the data, if the current data is empty
  if (is.null(current_data)) {
    get_bugzilla()
  } else {
    get_bugzilla(max(current_data[[&#39;last_change_time&#39;]]))
  }
})
ckbdata_updated &lt;- reactive({
  current_data &lt;- ckbdata()
  # Update the local copy in case of modification or bug
  new_data &lt;- get_bugzilla(max(current_data[[&#39;last_change_time&#39;]]))
  if (length(new_data) &gt; 0) {
    current_data &lt;- current_data[!(current_data$id %in% new_data[[&#39;id&#39;]]),]
    current_data &lt;- rbind(current_data, new_data)
  }
  current_data
})

Cheers

答案2

得分: 0

以下是翻译好的部分:

"The solution appears to be fairly easy, despite being a challenge to find good examples. The key thing was to store the results of the first slow request as part of the creation of the reactiveValues, and to have an isolated copy of that inside the observe so that it can check if there are any new rows, and process them accordingly."

"这个解决方案似乎相当简单,尽管寻找好的示例是一项挑战。关键是将第一个慢请求的结果作为reactiveValues的创建的一部分进行存储,并在observe内部有一个隔离的副本,以便它可以检查是否有新的行,并相应地处理它们。"

poll <- reactiveTimer(intervalMs = 10000)

values <- reactiveValues(ckbdata = get_bugzilla())

observe({
    poll()
    wip <- isolate(values$ckbdata)
    new <- get_bugzilla(max(wip[['last_change_time']]))
    if (length(new) > 0) {
        wip <- wip[!(wip$id %in% new[['id']]),]
        values$ckbdata <- rbind(wip, new)
    }
})
英文:

The solution appears to be fairly easy, despite being a challenge to find good examples. The key thing was to store the results of the first slow request as part of the creation of the reactiveValues, and to have an isolated copy of that inside the observe so that it can check if there are any new rows, and process them accordingly.

poll&lt;-reactiveTimer(intervalMs = 10000)

values&lt;-reactiveValues(ckbdata=get_bugzilla())

observe({
	poll()
	wip&lt;-isolate(values$ckbdata)
	new&lt;-get_bugzilla(max(wip[[&#39;last_change_time&#39;]]))
	if(length(new)&gt;0){
		wip&lt;-wip[!(wip$id %in% new[[&#39;id&#39;]]),]
		values$ckbdata&lt;-rbind(wip,new)
	}
})

huangapple
  • 本文由 发表于 2023年2月24日 17:20:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554717.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定