Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
759 views
in Technique[技术] by (71.8m points)

r - Shiny: Switching between reactive data sets with rhandsontable

In the below toy example I have two data sets df1 and df2. The data sets are output to an interactive table using shiny & rhandsontable. My issue is that the output$out only recognizes the shift in data sets if the user hasn't edited the data set in the shiny application as indicated by is.null(input$out).

How do I fix the below code to load either df1 or df2 when input$df changes when input$out isn't null?

require(rhandsontable)
require(shiny)

df1 <- data.frame(col1 = rnorm(20),
                  col2 = rep(T, 20))

df2 <- data.frame(col1 = rnorm(20),
                  col2 = rep(F, 20))

funcX <- function(x) {
  x$out <- ifelse(x$col2 == T, x$col1 * 1.5, x$col1)
  x$out
}

df2$out <- funcX(df2)
df1$out <- funcX(df1)

server <- function(input, output) {

  df <- reactive({
    if (input$df == "df1") {
      df <- df1
    } else {
      df <- df2
    }
    df
  })

  output$out <- renderRHandsontable({
    if (is.null(input$out)) {
      hot <- rhandsontable(df())
    } else {
      str(input$out)
      hot <- hot_to_r(input$out)
      hot$out <- funcX(hot)
      hot <- rhandsontable(hot)
    }
    hot
  })
}

ui <- fluidPage(sidebarLayout(sidebarPanel(
  selectInput(
    'df', 'Select data.frame:',
    choices = c('df1', 'df2'),
    selected = 'df1'
  )
),
mainPanel(rHandsontableOutput("out"))))

shinyApp(ui = ui, server = server)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could use reactiveValues to store the df1 and df2 data frames, and update these values when they are modified. Here's an example server.R code:

server <- function(input, output) {

  values = reactiveValues()
  values[["df1"]] <- df1
  values[["df2"]] <- df2

  observe({   
    if (!is.null(input$out)) {  
      temp <- hot_to_r(input$out)
      temp$out <- funcX(temp)
      if (isolate(input$df) == "df1") {       
        values[["df1"]] <- temp
      } else {
        values[["df2"]] <- temp
      }
    }
  })

  df <- reactive({
    if (input$df == "df1") {
      df <- values[["df1"]]
    } else {
      df <- values[["df2"]]
    }
    df
  })

  output$out <- renderRHandsontable({
    hot <- rhandsontable(df())
    hot
  })
}

When the table is changed, the correct df1 or df2 is updated in the reactive values. In the observer, the input$df is isolated so that this part of the code only reacts to when the user changes the tables.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...