英文:
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<-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
})
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 <- reactiveTimer(intervalMs = 10000)
ckbdata <- reactive()
poll()
current_data <- 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[['last_change_time']]))
}
})
ckbdata_updated <- reactive({
current_data <- ckbdata()
# Update the local copy in case of modification or 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
})
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<-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)
}
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论