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
864 views
in Technique[技术] by (71.8m points)

r - Add columns to a reactive data frame in Shiny and update them

I would like to be able to calculate a new column of data based on dividing one column by another, with both original columns selected by a user input. I would like to have this calculated data joined to the original table (or a copy of it).

I have managed to figure out how to make a dataframe that reacts to the column input selection, and I have managed to make a calculation that divides one column by the other, but I have not been able to make a final dataframe that includes all of the original columns as well as the new calculated one.

Here is a mock up I have made using the built in Iris data. It displays the data for the columns selected in the first table, and the calculation in the second table (you will need to scroll down quite far to see this).

How can I join this calculated data to the original source?

Many thanks

#Ui        
pageWithSidebar(
      headerPanel('Calculate Column'),
      sidebarPanel(

        #select variables from iris dataset
        selectInput('xcol', 'X Variable', names(iris)),
        selectInput('ycol', 'Y Variable', names(iris),
                    selected=names(iris)[[2]])
      ),
      mainPanel(
        #display the selected variables
            tableOutput("view"),
         #display the calculated variable
            tableOutput("view2")
      )
    )


#Server
        function(input, output, session) {

      # Combine the selected input variables into a new data frame
      selectedData <- reactive({
        iris[, c(input$xcol, input$ycol),]
      })


      # divide one variable selection by the other
      selectedData2 <- reactive({
                iris$new<-iris[, c(input$xcol)]/iris[, c(input$ycol)]

        })

      # create data output for selected variables
      output$view <- renderTable({selectedData()
      })

      # create data output for calculated variable
      output$view2 <- renderTable({selectedData2()
      })

    }
See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

You forget that iris is NOT a reactive element, so your code can't work. You have two options here:

  • creating a reactive value to store that data frame, using reactive().
  • creating a list of "global" reactive values in which you can store the updated data frame, using reactiveValues().

Using global reactive expressions with reactiveValues

Using reactiveValues you can make a list of reactive expressions much like input and output are. In the example below I use it to store the data frame iris as globals$mydf. Then you can use eg observe to change the value reactively, as in the following server function:

#Server
server <- function(input, output, session) {

  globals <- reactiveValues(
    mydf = iris
  )

  observe({
    thedf <- globals$mydf
    newvar <- thedf[[input$xcol]] / thedf[[input$ycol]]
    globals$mydf$ratio <- newvar
  })


  # create data output for selected variables
  output$view <- renderTable({
    globals$mydf
  })
}

using reactive()

You can make two reactive expressions that depend on eachother:

  • one that selects the variables and calculates that ratio
  • one that combines this result with the selected variables

Your server would look like this :

server <- function(input, output, session) {

  newdf <- reactive({
    cbind(
      iris[c(input$xcol, input$ycol)],
      Ratio = newvar()
    )
  })

  newvar <- reactive({
    iris[[input$xcol]] / iris[[input$ycol]]
  })

  # create data output for selected variables
  output$view <- renderTable({
    newdf()
  })

}

Although you beliefe this is not what you're looking for, you can use newdf() in other code just like you would use globals$mydf in the previous example. reactiveValues() especially pays off if different parts of your code have to be able to change the data frame.


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

...