English 中文(简体)
如何将R模块链接在一起?
原标题:How to chain together R modules?

在下面的R Shiny代码中,我展示了用于模块化反应数据处理的示例代码。代码包含在两个独立的R文件中:一个是基础应用程序,另一个是链接到基础应用程序的模块应用程序。基本应用程序向一个单独的模块发送一个反应式数据帧(df())和用于乘以数据帧值的用户输入(输入$svc

请注意运行乘法计算的模块中的反应式data()对象。我想将data()对象发送到单独的R文件中的第二个模块,该文件运行单独的计算,例如向data生成的每个数据帧单元添加值10,然后将这些结果发送回第一个模块,以便通过UI在第二个表中进行渲染。

如何做到这一点?

基本应用程序代码:

library(shiny)
library(DT)

source("C:/Users/User/Desktop/testModule1.R")

ui <- fluidPage(
  mainPanel(
    DTOutput("table"),
    sliderInput("svc",   , min = 0, max = 10, value = 1),
    allocTbl_ui("tblModule")  
  )
)

server <- function(input, output) {
  df <- data.frame(A = 1:3, B = 4:6, C = 7:9)
  
  output$table <- renderDT({datatable(df)})
  
  allocTbl_server(
    "tblModule",
    df = reactive(df),  
    svc = reactive(input$svc)
  )
}

shinyApp(ui, server)

模块应用程序代码:

# Module file name: testModule1.R

allocTbl_ui <- function(id) {
  ns <- NS(id)
  DTOutput(ns("tbl"))
}

allocTbl_server <- function(id, df, svc) {
  moduleServer(id, function(input, output, session) {
    output$tbl <- renderDT({
      data <- df() * as.numeric(svc())
      datatable(data)
    })
  })
}
最佳回答

在第一个模块中,将更新后的数据创建为响应数据,并将其返回到app_server,从那里可以将其传递给第三个模块。

library(DT)
# first module
allocTbl_ui <- function(id) {
    ns <- NS(id)
    DTOutput(ns("tbl"))
}
# first module server    
allocTbl_server <- function(id, df, svc) {
    moduleServer(id, function(input, output, session) {
        # store updated data as a reactive
        new_dat <- reactive({
            df() * as.numeric(svc())
        })
        output$tbl <- renderDT({
            datatable(new_dat())
        })
        # return updated data
        return(new_dat)
    })
}

# second module
mod_2_ui <- function(id){
    ns <- NS(id)
    DTOutput(ns( tbl2 ))
}
# adds 10 to df and shows as DT
mod_2_server <- function(id, upd_dat2){
    moduleServer(id, function(input, output, session){
        output$tbl2 <- renderDT({
            data <- upd_dat2() + 10
            datatable(data)
        })
    })
}

ui <- fluidPage(
    mainPanel(
        DTOutput("table"),
        sliderInput("svc",   , min = 0, max = 10, value = 1),
        allocTbl_ui("tblModule"), 
        mod_2_ui( mod2 ) # add second module
    )
)

server <- function(input, output) {
    df <- data.frame(A = 1:3, B = 4:6, C = 7:9)
    
    output$table <- renderDT({datatable(df)})
    
    # store returned value from first module
    upd_dat <- allocTbl_server("tblModule",
                               df = reactive(df),
                               svc = reactive(input$svc))
    
    # send this returned value to second module
    mod_2_server( mod2 , upd_dat)
}
shinyApp(ui, server)
问题回答

下面是部分解决这个问题的另一种方法,使用一个添加10的函数,而不是使用带有名称空间的模块。这有助于将代码“划分”为单独的R文件。

基本应用程序:

library(shiny)
library(DT)

source("C:/Users/User/Desktop/testModule1.R")

ui <- fluidPage(
  mainPanel(
    DTOutput("table1"),  
    sliderInput("svc",   , min = 0, max = 10, value = 1),
    allocTbl_ui("tblModule")  
  )
)

server <- function(input, output) {
  df <- data.frame(A = 1:3, B = 4:6, C = 7:9)
  
  output$table1 <- renderDT({
    datatable(df, caption = "Table 1")  
  })
  
  allocTbl_server(
    "tblModule",
    df = reactive(df),
    svc = reactive(input$svc)
  )
}

shinyApp(ui, server)

模块1:

# Module file name: testModule1.R

source("C:/Users/User/Desktop/testModule2.R")

allocTbl_ui <- function(id) {
  ns <- NS(id)
  DTOutput(ns("tbl"))
}

allocTbl_server <- function(id, df, svc) {
  moduleServer(id, function(input, output, session) {
    output$tbl <- renderDT({
      data <- cbind(A = df()[, "A", drop = FALSE], 
                    mult_A = df()[, "A"] * as.numeric(svc())
      )
      updatedData <- updateData(data, as.numeric(svc()))
      datatable(updatedData, 
                caption = "Table 2", 
                rownames = TRUE, 
                options = list(
                  columnDefs = list(
                    list(
                      className =  dt-center , 
                      targets = "_all"
                    )
                  )
                ), 
                colnames = c("A", "mult_A", "add_A"))
    })
    
  })
}

模块2:

updateData <- function(df, svc) {
  mult_A <- df[, "mult_A"]
  add_A <- mult_A + 10
  updatedData <- cbind(df, add_A)
  updatedData
}




相关问题
How to plot fitted model over observed time series

This is a really really simple question to which I seem to be entirely unable to get a solution. I would like to do a scatter plot of an observed time series in R, and over this I want to plot the ...

REvolution for R

since the latest Ubuntu release (karmic koala), I noticed that the internal R package advertises on start-up the REvolution package. It seems to be a library collection for high-performance matrix ...

R - capturing elements of R output into text files

I am trying to run an analysis by invoking R through the command line as follows: R --no-save < SampleProgram.R > SampleProgram.opt For example, consider the simple R program below: mydata =...

R statistical package: wrapping GOFrame objects

I m trying to generate GOFrame objects to generate a gene ontology mapping in R for unsupported organisms (see http://www.bioconductor.org/packages/release/bioc/vignettes/GOstats/inst/doc/...

Changing the order of dodged bars in ggplot2 barplot

I have a dataframe df.all and I m plotting it in a bar plot with ggplot2 using the code below. I d like to make it so that the order of the dodged bars is flipped. That is, so that the bars labeled "...

Strange error when using sparse matrices and glmnet

I m getting a weird error when training a glmnet regression. invalid class "dgCMatrix" object: length(Dimnames[[2]]) must match Dim[2] It only happens occasionally, and perhaps only under larger ...

Generating non-duplicate combination pairs in R

Sorry for the non-descriptive title but I don t know whether there s a word for what I m trying to achieve. Let s assume that I have a list of names of different classes like c( 1 , 2 , 3 , 4 ) ...

Per panel smoothing in ggplot2

I m plotting a group of curves, using facet in ggplot2. I d like to have a smoother applied to plots where there are enough points to smooth, but not on plots with very few points. In particular I d ...

热门标签