Reactive: assign a manipulated dataframe to a reactive object


#1

Hello, I think it is a basic issue on reactivity: I want to manipulate data inside reactive in order to obtain a cleaned dataset usable inside the renderDataTable expression avoiding the manipulation each time I change the inputSlider value.
The problem is in the reactive block (lines 93-95). Thank you in advance.

# Module UI function
csvFileInput <- function(id, label = "CSV file") {
    # Create a namespace function using the provided id
    ns <- NS(id)
    
    tagList(
        fileInput(ns("file"), label),
        #checkboxInput(ns("heading"), "Has heading"),
        selectInput(ns("separator"), "Separator", c(';', ','))
    )
}



# Module server function
csvFile <- function(input, output, session, stringsAsFactors) {
    # The selected file, if any
    userFile <- reactive({
        # If no file is selected, don't do anything
        validate(need(input$file, message = FALSE))
        input$file
    })
    
    # The user's data, parsed into a data frame
    dataframe <- reactive({
        read.csv(userFile()$datapath,
                 #header = input$heading,
                 stringsAsFactors = stringsAsFactors,
                 sep = input$separator)
        
    })
    
    
    # We can run observers in here if we want to
    observe({
        msg <- sprintf("File %s was uploaded\nStandardizing Enduser Names...", userFile()$name)
        cat(msg, "\n")
    })
    
    
    # Return the reactive that yields the data frame
    return(dataframe)
}

#####



library(shiny)

ui <- fluidPage(
    
    # Application title
    titlePanel("Transaction forecast and Probability of being active"),
    
    # Sidebar  
    sidebarLayout(
        sidebarPanel(
            csvFileInput("orders", "Orders data (.csv format)"),
            hr(),
            
            sliderInput('tw', 'Week time window', min = 4, max = 52, value = 8)
            
        ),
        
        mainPanel(
            tabsetPanel(type = "tabs",
                        tabPanel("Customers", dataTableOutput("customers") )
            )
            
        )
    )
)


server <- function(input, output, session) {
    
    options(shiny.maxRequestSize = 20*1024^2)
    library(tidyverse)
    library(BTYD)
    
    
    df <- callModule(csvFile, "orders", stringsAsFactors = TRUE)
    
    mydf = reactive({
        df = df()
		
		###THIS IS NOT WORKING!!!
		
        df$Document.Date = as.Date(df$Document.Date)
        df$Enduser.Name = tolower(df$Enduser.Name)
        df$Enduser.Name = as.factor(gsub('[.]', '', df$Enduser.Name))
        
        colnames(df) = c('cust', 'date', 'sales')
    })
    
    
    output$customers <- renderDataTable({

        df = mydf()

        
        
        elog <- dc.MergeTransactionsOnSameDate(df)
        VPKCBS <- elog2cbs(elog, T.cal = "2018-06-01", units = 'week')

        params <- mbgcnbd.EstimateParameters(VPKCBS)
        params
        
        x_vec = VPKCBS$x
        t.x_vec = VPKCBS$t.x
        T.cal_vec = VPKCBS$T.cal
        ET = mbgcnbd.ConditionalExpectedTransactions(params, T.star = input$tw, x_vec, t.x_vec, T.cal_vec);ET
        pA = mbgcnbd.PAlive(params, x_vec, t.x_vec, T.cal_vec);pA
        out = data.frame(VPKCBS$cust, ET, pA) 
        out = out %>% arrange(desc(ET))
        colnames(out) = c('Customer', 'Expected Transactions', 'P(Active)')
        
        out
        
        #####
        
    }) #End customer tab
    
}

shinyApp(ui, server)

#2

Hi @nmanca1992

I don't see why it's not working. Don't forget to return the dataframe (df) at the end of the reactive.

mydf <- reactive({
  df <- df()
		
  df$Document.Date <- as.Date(df$Document.Date)
  df$Enduser.Name <- tolower(df$Enduser.Name)
  df$Enduser.Name <- as.factor(gsub('[.]', '', df$Enduser.Name))

  colnames(df) <- c('cust', 'date', 'sales')
  df
})

- Barret


#3

Thank you Barret.
I exactly forgot to return the object.