使用类似于函数的 R shiny 模块输出
Using R shiny module outputs similar to functions
我正在尝试使用以下代码实现以下目标:
- Import.Excel.Data.UI 和 Import.Excel.Data.Server 构成模块的 UI 和服务器块,这将帮助我输入“a) Excel 文件路径,b) Sheet 名称,c) 数据范围和 d) 复选框输入”。这个想法是将数据框作为输出,每行包含上述 4 列。
- Import.Excel.Data.App 是我尝试使用上述模块输出的地方。这个想法是使用模块中生成的数据帧并将每一行分别传递给 readXLS 函数。在代码中,我通过
行分配此输出
ABC <- Import.Excel.Data.Server("File1")
- 我的问题:我以为我在上面的模块 1 中生成了一个数据框。但是,当我尝试提取 class 时,结果是 class 字符而不是 class data.frame。我正在尝试通过代码
打印 class
output$ABC.class <- renderText(class(ABC()))
output$ABC.matrix <- renderPrint(ABC())
在 Import.Excel.Data.App
的服务器部分
我无法找出错误 - 虽然我不确定我分配它的方式(如上面 2 所示)是否正确。
如有任何帮助,我们将不胜感激。
完整代码如下
模块代码
library(shiny)
Import.Excel.Data.UI <- function(id){
ns <- NS(id)
tagList(
actionButton(ns("AddExcelDataButton"), label = "Click Here to Add Excel Data"),
verbatimTextOutput(ns("XLmatrix"))
)
}
Import.Excel.Data.Server <- function(id){
moduleServer(id, function(input, output, session){
ns <- session$ns
observeEvent(eventExpr = input$AddExcelDataButton,
insertUI(selector=paste0("#",ns("AddExcelDataButton")),
multiple=TRUE,
where = "afterEnd",
ui = tags$hr(
tags$div(fileInput(inputId = ns(paste0("ExcelFile",input$AddExcelDataButton)),
label = paste0("Path for File",input$AddExcelDataButton),
multiple = FALSE),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(textInput(inputId = ns(paste0("ExcelSheetName",input$AddExcelDataButton)),
label = paste0("Excel Sheet Name",input$AddExcelDataButton),
value = "Data"),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(textInput(inputId = ns(paste0("ExcelSheetRange",input$AddExcelDataButton)),
label = paste0("Excel Sheet Range", input$AddExcelDataButton),
value = "C6:AL10000"),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(checkboxInput(inputId = ns(paste0("ExcelFileCheck",input$AddExcelDataButton)),
label = paste0("Check to Use File", input$AddExcelDataButton),
value = TRUE),
style = "display:inline-block; vertical-align:center"
)#end of tags$div
)#end of tags$hr
)#end of insertUI
)#end of observeEvent
XLdata <- reactive({
for (i in 1: input$AddExcelDataButton)
{
temp.filepath <- input[[paste0("ExcelFile",i)]]$datapath
temp.sheetname <- input[[paste0("ExcelSheetName",i)]]
temp.sheetrange <- input[[paste0("ExcelSheetRange",i)]]
temp.filecheck <- input[[paste0("ExcelFileCheck",i)]]
row.temp <- cbind(temp.filepath, temp.sheetname, temp.sheetrange, temp.filecheck)
ifelse(i<=1,
{
XLdata.matrix <- row.temp
},#end of if condition in ifelse i<=1
{
XLdata.matrix <- rbind(XLdata.matrix, row.temp)
} #end of else in ifelse i<=1
)#end of ifelse brackets
}#end of for-loop
XLdata.matrix <- as.data.frame(XLdata.matrix)
XLdata.matrix
})#end of reactive for XLdata
output$XLmatrix <- renderPrint(XLdata())
})#end of module server
}
应用代码
Import.Excel.Data.App <- function(){
ui <- fluidPage(
Import.Excel.Data.UI("File1"),
textOutput("ABC.class"),
verbatimTextOutput("ABC.matrix")
)
server <- function(input, output, session){
ABC <- Import.Excel.Data.Server("File1")
output$ABC.class <- renderText(class(ABC()))
output$ABC.matrix <- renderPrint(ABC())
}
shinyApp(ui, server)
}
Import.Excel.Data.App()
你们非常亲密。您只需要 return 反应对象 XLdata
,并在反应对象内部使用 req()
。试试这个
Import.Excel.Data.Server <- function(id){
moduleServer(id, function(input, output, session){
ns <- session$ns
observeEvent(eventExpr = input$AddExcelDataButton,
insertUI(selector=paste0("#",ns("AddExcelDataButton")),
multiple=TRUE,
where = "afterEnd",
ui = tags$hr(
tags$div(fileInput(inputId = ns(paste0("ExcelFile",input$AddExcelDataButton)),
label = paste0("Path for File",input$AddExcelDataButton),
multiple = FALSE),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(textInput(inputId = ns(paste0("ExcelSheetName",input$AddExcelDataButton)),
label = paste0("Excel Sheet Name",input$AddExcelDataButton),
value = "Data"),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(textInput(inputId = ns(paste0("ExcelSheetRange",input$AddExcelDataButton)),
label = paste0("Excel Sheet Range", input$AddExcelDataButton),
value = "C6:AL10000"),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(checkboxInput(inputId = ns(paste0("ExcelFileCheck",input$AddExcelDataButton)),
label = paste0("Check to Use File", input$AddExcelDataButton),
value = TRUE),
style = "display:inline-block; vertical-align:center"
)#end of tags$div
)#end of tags$hr
)#end of insertUI
)#end of observeEvent
XLdata <- reactive({
req(input[[paste0("ExcelFile",input$AddExcelDataButton)]])
for (i in 1: input$AddExcelDataButton)
{
temp.filepath <- input[[paste0("ExcelFile",i)]]$datapath
temp.sheetname <- input[[paste0("ExcelSheetName",i)]]
temp.sheetrange <- input[[paste0("ExcelSheetRange",i)]]
temp.filecheck <- input[[paste0("ExcelFileCheck",i)]]
row.temp <- cbind(temp.filepath, temp.sheetname, temp.sheetrange, temp.filecheck)
ifelse(i<=1,
{
XLdata.matrix <- row.temp
},#end of if condition in ifelse i<=1
{
XLdata.matrix <- rbind(XLdata.matrix, row.temp)
} #end of else in ifelse i<=1
)#end of ifelse brackets
}#end of for-loop
XLdata.matrix <- as.data.frame(XLdata.matrix)
XLdata.matrix
})#end of reactive for XLdata
output$XLmatrix <- renderPrint(XLdata())
return(XLdata)
})#end of module server
}
我正在尝试使用以下代码实现以下目标:
- Import.Excel.Data.UI 和 Import.Excel.Data.Server 构成模块的 UI 和服务器块,这将帮助我输入“a) Excel 文件路径,b) Sheet 名称,c) 数据范围和 d) 复选框输入”。这个想法是将数据框作为输出,每行包含上述 4 列。
- Import.Excel.Data.App 是我尝试使用上述模块输出的地方。这个想法是使用模块中生成的数据帧并将每一行分别传递给 readXLS 函数。在代码中,我通过 行分配此输出
ABC <- Import.Excel.Data.Server("File1")
- 我的问题:我以为我在上面的模块 1 中生成了一个数据框。但是,当我尝试提取 class 时,结果是 class 字符而不是 class data.frame。我正在尝试通过代码 打印 class
output$ABC.class <- renderText(class(ABC()))
output$ABC.matrix <- renderPrint(ABC())
在 Import.Excel.Data.App
的服务器部分我无法找出错误 - 虽然我不确定我分配它的方式(如上面 2 所示)是否正确。
如有任何帮助,我们将不胜感激。
完整代码如下
模块代码
library(shiny)
Import.Excel.Data.UI <- function(id){
ns <- NS(id)
tagList(
actionButton(ns("AddExcelDataButton"), label = "Click Here to Add Excel Data"),
verbatimTextOutput(ns("XLmatrix"))
)
}
Import.Excel.Data.Server <- function(id){
moduleServer(id, function(input, output, session){
ns <- session$ns
observeEvent(eventExpr = input$AddExcelDataButton,
insertUI(selector=paste0("#",ns("AddExcelDataButton")),
multiple=TRUE,
where = "afterEnd",
ui = tags$hr(
tags$div(fileInput(inputId = ns(paste0("ExcelFile",input$AddExcelDataButton)),
label = paste0("Path for File",input$AddExcelDataButton),
multiple = FALSE),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(textInput(inputId = ns(paste0("ExcelSheetName",input$AddExcelDataButton)),
label = paste0("Excel Sheet Name",input$AddExcelDataButton),
value = "Data"),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(textInput(inputId = ns(paste0("ExcelSheetRange",input$AddExcelDataButton)),
label = paste0("Excel Sheet Range", input$AddExcelDataButton),
value = "C6:AL10000"),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(checkboxInput(inputId = ns(paste0("ExcelFileCheck",input$AddExcelDataButton)),
label = paste0("Check to Use File", input$AddExcelDataButton),
value = TRUE),
style = "display:inline-block; vertical-align:center"
)#end of tags$div
)#end of tags$hr
)#end of insertUI
)#end of observeEvent
XLdata <- reactive({
for (i in 1: input$AddExcelDataButton)
{
temp.filepath <- input[[paste0("ExcelFile",i)]]$datapath
temp.sheetname <- input[[paste0("ExcelSheetName",i)]]
temp.sheetrange <- input[[paste0("ExcelSheetRange",i)]]
temp.filecheck <- input[[paste0("ExcelFileCheck",i)]]
row.temp <- cbind(temp.filepath, temp.sheetname, temp.sheetrange, temp.filecheck)
ifelse(i<=1,
{
XLdata.matrix <- row.temp
},#end of if condition in ifelse i<=1
{
XLdata.matrix <- rbind(XLdata.matrix, row.temp)
} #end of else in ifelse i<=1
)#end of ifelse brackets
}#end of for-loop
XLdata.matrix <- as.data.frame(XLdata.matrix)
XLdata.matrix
})#end of reactive for XLdata
output$XLmatrix <- renderPrint(XLdata())
})#end of module server
}
应用代码
Import.Excel.Data.App <- function(){
ui <- fluidPage(
Import.Excel.Data.UI("File1"),
textOutput("ABC.class"),
verbatimTextOutput("ABC.matrix")
)
server <- function(input, output, session){
ABC <- Import.Excel.Data.Server("File1")
output$ABC.class <- renderText(class(ABC()))
output$ABC.matrix <- renderPrint(ABC())
}
shinyApp(ui, server)
}
Import.Excel.Data.App()
你们非常亲密。您只需要 return 反应对象 XLdata
,并在反应对象内部使用 req()
。试试这个
Import.Excel.Data.Server <- function(id){
moduleServer(id, function(input, output, session){
ns <- session$ns
observeEvent(eventExpr = input$AddExcelDataButton,
insertUI(selector=paste0("#",ns("AddExcelDataButton")),
multiple=TRUE,
where = "afterEnd",
ui = tags$hr(
tags$div(fileInput(inputId = ns(paste0("ExcelFile",input$AddExcelDataButton)),
label = paste0("Path for File",input$AddExcelDataButton),
multiple = FALSE),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(textInput(inputId = ns(paste0("ExcelSheetName",input$AddExcelDataButton)),
label = paste0("Excel Sheet Name",input$AddExcelDataButton),
value = "Data"),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(textInput(inputId = ns(paste0("ExcelSheetRange",input$AddExcelDataButton)),
label = paste0("Excel Sheet Range", input$AddExcelDataButton),
value = "C6:AL10000"),
style = "display:inline-block; vertical-align:top"
),#end of tags$div
tags$div(checkboxInput(inputId = ns(paste0("ExcelFileCheck",input$AddExcelDataButton)),
label = paste0("Check to Use File", input$AddExcelDataButton),
value = TRUE),
style = "display:inline-block; vertical-align:center"
)#end of tags$div
)#end of tags$hr
)#end of insertUI
)#end of observeEvent
XLdata <- reactive({
req(input[[paste0("ExcelFile",input$AddExcelDataButton)]])
for (i in 1: input$AddExcelDataButton)
{
temp.filepath <- input[[paste0("ExcelFile",i)]]$datapath
temp.sheetname <- input[[paste0("ExcelSheetName",i)]]
temp.sheetrange <- input[[paste0("ExcelSheetRange",i)]]
temp.filecheck <- input[[paste0("ExcelFileCheck",i)]]
row.temp <- cbind(temp.filepath, temp.sheetname, temp.sheetrange, temp.filecheck)
ifelse(i<=1,
{
XLdata.matrix <- row.temp
},#end of if condition in ifelse i<=1
{
XLdata.matrix <- rbind(XLdata.matrix, row.temp)
} #end of else in ifelse i<=1
)#end of ifelse brackets
}#end of for-loop
XLdata.matrix <- as.data.frame(XLdata.matrix)
XLdata.matrix
})#end of reactive for XLdata
output$XLmatrix <- renderPrint(XLdata())
return(XLdata)
})#end of module server
}