R Shiny-是否可以嵌套反应函数? [英] R Shiny - Is it possible to nest reactive functions?

查看:72
本文介绍了R Shiny-是否可以嵌套反应函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在R-Shiny中.试图破坏一个很长的反应函数(数千行!).假设地,是否有可能嵌套条件反应函数,类似于:

In R-Shiny. Trying to break up a really long reactive function (thousands of lines!). Hypothetically, is it possible to nest conditional reactive functions, something similar to:

STATE_filter <- reactive({
 
   if(input$selectcounty ends with "-AL") {
    run AL_filter()
  }
  else if (input$selectstate ends with "-AR"){
    run AR_filter()
  }
  else {
    return("ERROR")
  }
})

编辑

非假设地,我试图基于美国各县的用户选择输入来创建嵌套的反应式过滤功能.选择县后,将在模式对话框中弹出circlepackeR图 .这是我正在使用的数据:

Non-hypothetically, I'm trying to create a nested reactive filtering function based on user select inputs of U.S. counties. Upon their selection of county, a circlepackeR graph should pop up in a modal dialog box. This is the data I am using:

dput(head(demographics))
structure(list(NAME = c("Autauga-AL", "Baldwin-AL", "Barbour-AL", 
"Bibb-AL", "Blount-AL", "Bullock-AL"), STATE_NAME = c("AL", "AL", 
"AL", "AL", "AL", "AL"), gender = structure(c(2L, 2L, 2L, 2L, 
2L, 2L), .Label = c("female", "male"), class = "factor"), hispanic = structure(c(2L, 
2L, 2L, 2L, 2L, 2L), .Label = c("hispanic", "nonhispanic"), class = "factor"), 
    race = structure(c(6L, 6L, 6L, 6L, 6L, 6L), .Label = c("asian", 
    "black", "islander", "native", "two or more", "white"), class = "factor"), 
    makeup = structure(c(2L, 2L, 2L, 2L, 2L, 2L), .Label = c("in combination", 
    "one race", "two or more"), class = "factor"), r_count = c(456L, 
    1741L, 114L, 96L, 320L, 44L), pathString = c("world/male/nonhispanic/white/one race", 
    "world/male/nonhispanic/white/one race", "world/male/nonhispanic/white/one race", 
    "world/male/nonhispanic/white/one race", "world/male/nonhispanic/white/one race", 
    "world/male/nonhispanic/white/one race")), row.names = c(NA, 
6L), class = "data.frame")

下面是我正在使用的反应函数的一个示例.这是一万多行的一小部分,我想嵌套"首先通过按州划分行(对于阿拉巴马州是AL,对于阿肯色州来说是AR)来分割代码,因此这是一段简洁的代码.

Here's an example of the reactive function I'm using below. It's a small subset of 10,000 + lines, and I want to "nest" it by splitting the lines by state (AL for Alabama, AR for Arkansas) first so it's a cleaner piece of code.

demographics_filter <- reactive({
   if(input$selectcounty == "Autauga-AL") {
    race_autauga <- subset.data.frame(demographics, NAME=="Autauga-AL")
    nodes_autauga <- as.Node(race_autauga)
  } 
  else if(input$selectcounty== "Baldwin-AL") {
    race_baldwinAL <-subset.data.frame(demographics, NAME=="Baldwin-AL")
    nodes_baldwinAL<- as.Node(race_baldwinAL)
  } 
 else if(input$selectcounty== "Ashley-AR") {
    race_AshleyAR <-subset.data.frame(race, NAME=="Ashley-AR")
    nodes_AshleyAR<- as.Node(race_AshleyAR)
  }
  else {
    return("ERROR!")
  }
})

最后,这是服务器中利用此功能的图形:

And finally, here's the graph in my server that's utilizing this function:

     output$circle_graph_of_demographics <- renderCirclepackeR({
      circlepackeR(demographics_filter(), size = "r_count"
    })  

推荐答案

就个人而言,如果单个功能/反应式的长度为1000几行,那么重构肯定有改进的空间!

Speaking personally, if a single function/reactive is 1000s of lines long, there's definitely room for improvement through refactorisation!

对于您提供给我们的 demographics_filter 反应式,我感到奇怪的是,在有效数据的情况下,它返回 NULL ,并且"错误!" (如果数据无效),那么我不确定如何在 output $ circle_graph_of_demographics 中成功使用它.如果您不需要它返回任何内容,那么 eventReactive(input $ selectcounty,{...})会更合适吗?

One thing I find strange about the demographics_filter reactive you've given us is that it returns NULL in the case of valid data and "ERROR!" in the case of invalid data, so I'm not sure how you can use it successfully in output$circle_graph_of_demographics. If you don't need it to return anything, then perhaps an eventReactive(input$selectcounty, {...}) would be more appropriate?

似乎您需要根据 input $ selectcounty 的值更改来创建(一组)节点和(一组)经过过滤的数据帧.目前尚不清楚为什么当 input $ selectcounty 例如是 Baldwin-AR 时,为什么需要一个节点和子集来用于 Autauga-Al ,这就是为什么我将设置为"在方括号中.

It looks as if you need to create both a (set of) nodes and a (set of) filtered data frames based on changes to the value of input$selectcounty. It's not clear why you need a node and subset for, say, Autauga-Al when input$selectcounty is, say, Baldwin-AR, which is why I've put "set of" in brackets.

根据您告诉我们的内容(没有MWE,不可能确定确切的内容适合您的需求),我会做类似的事情:

Based on what you've told us (without a MWE, it's impossible to be sure exactly what will suit your needs), I would do something like:

demographics_filter <- reactive({
  req(input$selectcounty)
  subset.data.frame(demographics, NAME==input$selectcounty)
})

demographics_node <- reactive({
  as.Node(demographics_filter())
})

应该提供一个紧凑的解决方案,该解决方案对于县和州名称的更改具有鲁棒性.如果我对您的理解正确,那么这将替换您的数千行,而只有七行.显然,您可能需要重构其余代码以考虑所做的更改.

which should provide a compact solution that is robust with respect to changes in county and state names. If I understand you correctly, this replaces your many-thousands-of-lines with just seven. Obviously, you may need to refactor the rest of your code to take account of your changes.

如果您确实需要过滤后的数据帧和节点集,那么我将执行以下操作:

If you do need sets of filtered data frames and nodes, then I'd do something like this:

v <- reactiveValues(
       demographics_filter=list(),
       demographics_nodes=list()
     )

eventReactive(input$selectcounty, {
  req(input$selectcounty)
  v$demographics_filter[[input$selectcounty]] <- subset.data.frame(demographics, NAME==input$selectcounty)
  v$demographics_node[[input$selectcounty]] <- as.Node(v$demographics_filter[[input$selectcounty]])
})

同样,它是一个紧凑,强大的解决方案,您可能需要在其他地方重构代码以考虑更改.

Again, it's a compact, robust solution, and you may need to refactor your code elsewhere to take account of the changes.

我的所有代码都未经测试,因为我没有要使用的 MWE .

All my code is untested because I don't have a MWE to work with.

这篇关于R Shiny-是否可以嵌套反应函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆