简体   繁体   中英

R change columns types using shiny, rhandson and DT

I have a shiny app, where a user can upload his csv into user_table() reactive expression, which is then shown to a user using DT renderDataTable() ; There is also RHandsontable with the types of columns from user_table() . User should be able to change the values in RHandsontable and click 'Apply' button, to apply changes to his table. (ie there is a 'number' column, and he wants to change it into 'character'). Here is how DT is rendered for a user:

main_table <- DT::renderDataTable({
    datatable(
        user_table()
    )
})

Here is how handsontable works:

dataTypes <- c("integer", "numeric", "factor", "character", "logical")
handsontable <- renderRHandsontable({
    if (!is.null(input$uploaded_file)) {
        if (is.null(input$hottest)) {
            DF = data.frame(Type = cbind(lapply(user_table(), typeof)),
                            stringsAsFactors = TRUE)
        } else {
            DF = hot_to_r(input$hottest)
        }
        DF$Type = factor(DF$Type, dataTypes)
        rhandsontable(DF, readOnly = FALSE) %>%
            hot_table(stretchH = 'all', rowHeaderWidth = 120) %>%
            hot_context_menu(allowRowEdit = FALSE, allowColEdit = FALSE)
    }
    else { return() }
})

Now I'm trying to do the following: after the apply button click, make a new table with user-changed types of columns, though I'm not sure how should it be done correctly. Should I use another reactive expression to do that? Is observeEvent the right thing to use for button onclick event? If something is unclear, please ask. Thanks in advance!

edit: I've come up with this function after browsing SO for some time:

convert.types <- function(obj, types){
        for(i in length(obj)){
            func <- switch(types[i],
                           integer = as.integer,
                           numeric = as.numeric,
                           factor = as.factor,
                           character = as.character,
                           logical = as.logical)
            obj[,i] <- func(obj[,i])
        }
        obj
    }

and use it with observeEvent:

observeEvent(input$button_table_convertion, {
    hottestVector <- as.vector(t(hot_to_r(input$hottest)))
    new_table <- convert.types(as.data.frame(user_table()), hottestVector)

Although, Rhandsontable is not reacting to user input; it just changes columns types to the same they've been already. Any workaround?

Seems to work that way:

  new_table <- eventReactive(input$button_table_convertion, {
            hottestVector <- as.vector(t(hot_to_r(input$handsontypes)))
            convert.types(data.frame(user_table()), hottestVector)
        })
  output$secondtable <- DT::renderDataTable({ datatable(new_table()) })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM