r - 在 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”或其他什么的作用是什么?)。
我确切地说我已经开发了一个完美运行的经典闪亮应用程序(服务器/用户界面,不使用模块),但我想让可视化更加“专业”......
谢谢你的帮助!
更新:出于好奇,我打印了“模型”输出:
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 ()
似乎“模型”变量不是预期的(即模型_1、模型_2 或模型_3)......为什么?
解决方案
问题是模块内部的环境基本上被视为函数中的环境。考虑以下代码
fun <- function(x) {
result <- x + 1
result ## return the result
}
fun(2)
result
#> Error: object 'result' not found
可以通过将函数的返回值保存在变量中来解决上述问题
res <- fun(2)
res
#> 3
您需要将相同的逻辑应用于您的模块:模块中的所有内容都必须由模块服务器函数返回,这就是selectModel
您的情况。
model <- callModule(selectModel,"mod")
如果不是这种情况,那么命名空间将毫无意义,因为多个模块会同时写入同一个变量。
重新审视您更一般的问题“callModule 是做什么的?”。基本上它使所有输入和输出ID都带有前缀。这意味着如果input$target_model
在带有 id 的模块内部使用mod
,这实际上会得到input[["mod-target_model"]]
。您可以将其视为为您的输入和输出 id 创建一个“文件夹”,以确保您的 id 不会相互冲突。在这个类比中,mod
将是文件夹名称,并且target_model
将是该文件夹内的文件。
推荐阅读
- microsoft-graph-api - 微软图表中带有坐标的站点或房间列表
- database-connection - Tomcat jdbc 连接池 - 删除放弃后未创建空闲连接
- asp.net-mvc - 在 MVC Core 应用程序中创建母版页
- angularjs - 未知提供者:uiCropperProvider <- uiCropper
- php - Laravel 检查状态并发送电子邮件
- angular5 - 在 PrimeNG p-table 'Column Resize' with Frozen Columns
- java - 在下一个方法调用之前 Asynctask 未完成下载
- jenkins - Jenkinsfile(脚本)将 shell $HOME 设置为 ${env.WORKSPACE}
- asp.net - ASP.NET MVC 5 - 使已删除用户的 cookie 无效
- python - python中是否有类似于sys.maxint的sys.minint?