繁体   English   中英

在R flexdashboard中使用闪亮的模块

[英]Using shiny modules in R flexdashboard

我尝试使用flexdashboard使单词嵌入的结果交互式化,但是我没有得到使用闪亮模块背后的逻辑。

在Rmd仪表板中,加载所需的库之后,我首先加载了要处理的3个模型:

---
title: "Embedding Explorer"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
    runtime: shiny
---

```{r setup, include=FALSE}
library(flexdashboard)
library(wordVectors)
library(plotly)
library(shiny)
library(shinyjs)
```

```{r global, include=FALSE}
model_1 = wordVectors::read.vectors('./models/word_embeddings_1.bin')
model_2 = wordVectors::read.vectors('./models/word_embeddings_2.bin')
model_3 = wordVectors::read.vectors('./models/word_embeddings_3.bin')
```

然后,我希望仪表板的每个组件都加载特定的模块。 例如,在边栏中,我想显示一个selectInput对象以选择模型之一。 为此,我编写了一个R脚本模块Models.R:

# UI function
selectModelInput <- function(id) {
  ns <- NS(id)
  tagList(
  selectInput(ns("target_model"),label="Target model",c("gloVe","Word2Vec","Fasttext"))
)
}

# Server function
selectModel <- function(input, output,session) {
   observeEvent(input$target_model,{
     if (input$target_model=="gloVe"){
       model = model_1
    }else if (input$target_model=="Word2Vec"){
      model = model_2
    }else if (input$target_model=="Fasttext"){
      model = model_3
    }
output$model <- model #add an output element
    })
}

因此,我在Rmd文件中调用此模块:

```{r sidepanel}
# include the module
source("./modules/Models.R")

# call the module
selectModelInput("mod")
model <- callModule(selectModel,"mod") #add model in variable

renderText("Vocabulary size:")
renderPrint(nrow(model))
renderText("Embeddings dim:")
renderPrint(ncol(model))

```

这样做,我收到一条错误消息,指出“模型”对象不存在。 也许问题在于模块无法从全局部分访问model_x? 还是我错过了一些允许将“模型”对象保存在某处的东西? 顺便说一句,我不太了解调用模块的行为(尤其是id参数“ mod”的作用是什么?)。

我想我已经开发了一个完美运行的经典Shiny应用程序(服务器/用户界面,未使用任何模块),但我想让Vizualization更加“专业” ...

谢谢你的帮助!

更新:出于好奇,我打印了“模型”输出:

selectModelInput("mod")
model <- callModule(selectModel,"mod")
renderPrint(model)

结果如下:

<Observer>
  Public:
.autoDestroy: TRUE
.autoDestroyHandle: function () 
.createContext: function () 
.ctx: environment
.destroyed: FALSE
.domain: session_proxy
.execCount: 2
.func: function (...) 
.invalidateCallbacks: list
.label: observeEvent(input$target_model)
.onDomainEnded: function () 
.onResume: function () 
.prevId: 13
.priority: 0
.suspended: FALSE
clone: function (deep = FALSE) 
destroy: function () 
initialize: function (observerFunc, label, suspended = FALSE, priority =  0, 
onInvalidate: function (callback) 
resume: function () 
run: function () 
self: Observer, R6
setAutoDestroy: function (autoDestroy) 
setPriority: function (priority = 0) 
suspend: function () 

似乎'model'变量不是预期的值(即model_1,model_2或model_3)...为什么?

问题在于,基本上像对待函数一样对待模块内部的环境。 考虑以下代码

fun <- function(x) {
  result <- x + 1
  result ## return the result
}

fun(2)

result
#> Error: object 'result' not found

可以通过将函数的返回值保存在变量中来解决上述问题

res <- fun(2)
res
#> 3

您需要对模块应用相同的逻辑:模块中的所有内容都必须由module-server-function返回,在本例中为selectModel

model <- callModule(selectModel,"mod")

如果不是这种情况,则命名空间根本没有任何意义,因为几个模块会同时写入同一变量。

关于您的更笼统的问题“ callModule做什么?”。 基本上,它使所有输入和输出ID都带有前缀。 这意味着,如果在具有id mod的模块内部使用input$target_model ,则实际上将获得input[["mod-target_model"]] 您可以认为这是为输入和输出ID创建一个“文件夹”,以确保您的ID不会相互冲突。 以此类推, mod将是文件夹名称,而target_model将是该文件夹内的文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM