Search code examples
rdataframerandom-forestpredictionshinydashboard

How to use reactiveElements inside data.frame()


I have imported my datasets into my app.R . There is a problem in adding the user inputs to the dataframe and how to get the output as Yes or No after prediction and display the output after using predict() this is my ui dashboad body:

     box(mainPanel("ENTER THE DETAILS :",br(),br(),textInput("name","Name :","Name Here"),br(),
                                                numericInput("uiage",'Age :',value = 25,min = 25,max = 100),br(),
                                                 radioButtons("uigender","Gender :",c("Male","Female"),inline=TRUE),br(),
                                                textInput("uipurpose","Purpose Of Loan :","Car Loan"),br(),
                                                numericInput("uicredhist",'Cibil Score :',min=1,max=10,value = 9),br(),
                                                numericInput("uicredamt", 'Credit Amount',value = 10000),br(),
                                                numericInput("uicommitment","Intallment Commitment",value =2,min=0,max=6),br(),
                                                radioButtons("uiemplymentstatus","Employment Status :",c("Yes","No"),inline = TRUE),br(),br(),
                                                numericInput("uicheckingstatus",'Checking Status :',min=1,max=10,value = 9),br(),
                                                textInput("uipropmag","Property Magnitude:","real-estate/life-insurance/car/jewels"),br(),
                                                radioButtons("uihousing","Housing :",c("own","rent"),inline = TRUE),br(),
                                                radioButtons("uiforeign","Foreign Worker :",c("yes","no"),inline=TRUE),br(),
                                                radioButtons("uieducation","Educational Qualities :",c("Skilled","Un-Skilled"),inline = TRUE),br(),
                                            actionButton("submit",label = "Submit"),textOutput("text1")))


This is my server logic to get user inputs :

    text_reactive1 <- eventReactive( input$submit, {
    userage <- input$uiage
  })


    text_reactive2 <- eventReactive(input$submit,{
    usercredithist <- input$uicredhist
  })



    text_reactive3 <- eventReactive(input$submit,{
    usercredamt <- input$uicredamt
  })


    text_reactive4 <- eventReactive(input$submit,{
    usercommit <- input$uicommitment
  })

this is my algorithm :


    fit <- randomForest(df$class~df$age+df$credit_history+df$credit_amount+df$installment_commitment, data=datfr$df)

 randpred <-reactive({ predict(fit,dframe=data.frame(text_reactive1(),text_reactive2(),text_reactive3(),text_reactive4()))})

  output$text1 <- renderText({
  paste("Input cred hist is :",randpred())
  })

I need my output as Yes or no .. can somebody help me solve this..

enter image description here


Solution

  • There are many things going on with this question and not very much of it is clear.

    I'm assuming these are the following problems you need help with

    1. Applying Random Forests Correctly
    2. Accessing input values from shiny

    Random Forests

    A lot of what is wrong with your code is using the incorrect arguments, since you did not provide a reproducible example of data, I will continue with the iris dataset.

    fit <- randomForest(formula = Species~Sepal.Width+Sepal.Length,
                        data = iris)
    

    when you call randomForest with formula notation, you do not need to (and probably shouldn't) access the vectors with $ but instead use their symbol names. This is mostly a distinction with using predict on new data.

    predict's argument to test your model on new data is newdata not dframe. Since dframe is never evaluated (because of lazy evaluation), the default of the predict function just returns the values of the original predicted values. I'm going to circle back to your predicted values in a second, but first I want to show what you need to do with newdata argument.

    #If I did random forests accessing vectors with $
    dim(iris)
    #[1] 150   5
    fit <- randomForest(formula = iris$Species~iris$Sepal.Width+iris$Sepal.Length,
                        data = iris)
    predict(fit) # default returns predicted values
    predict(fit, newdata = data.frame(Sepal.width = c(1:10), Sepal.Length = c(21:30)) #throws an error
    #Error in x[...] <- m : NAs are not allowed in subscripted assignments
    #In addition: Warning message:
    #'newdata' had 10 rows but variables found have 150 rows
    

    Because the randomForest formula argument was given a vector of length 150, it expects the new dataframe to be that size. This is still an issue though because even if newdata dimensions are satisfied, the fit is almost always the same...

    test1 <- predict(fit, newdata = data.frame(rnorm(150,2194192,409), rnrom(150, -12359,21885999)))
    test2 <- predict(fit, newdata = data.frame(rnorm(150, 10000),rnorm(150, -1000000)))
    all(test1==test2)
    #TRUE
    

    Using the correct notation, then :

    fit <- randomForest(formula = Species~Sepal.Width+Sepal.Length,
                        data = iris)
    predict(fit, newdata = data.frame(Sepal.Width = 1:10, Sepal.Length = 10:1))
    #        1         2         3         4         5         6         7         8         9        10 
    #virginica virginica virginica virginica    setosa    setosa    setosa    setosa    setosa    setosa 
    #Levels: setosa versicolor virginica
    

    Note: the newdata data frame must have the same column headers as the response values in your randomForest fit, otherwise you will get an error.

    Now I want to talk about your predictive variable. Since you have not provided a sample of what your data looks like I am assuming df$class is your what you are trying to classify. Since your predict output is providing you with a number - I'm guessing df$class is either a continuous value or stored as a integer of 0 or 1. If you wish to have randomForest return either a "yes" or a "no", then df$class should be a factor vector containing either "yes" or "no".

    Server logic

    Again, I don't know for sure if there are any errors in the code you presented because there is not reproducible example, but I would condense your server logic as such.

    server <- function(input, output){
    #somewhere load and assign datfr
    fit <- randomForest(class~age+credit_history+credit_amount+installment_commitment,
                        data=datfr$df)
    rv <- reactiveValues(userage = NULL,
                         usercredithist = NULL,
                         usercredamt = NULL,
                         usercommit = NULL)
    observeEvent(input$submit,{
        req(input$uiage, input$uicredhist, input$uicredamt, input$uicommitment)
        rv$userage <- input$uiage
        rv$usercredithist <- input$uicredhist
        rv$usercredamt <- input$uicredamt
        rv$usercommit <- input$uicommitment
        }
    )
    
    randpred <-reactive({
        predict(fit,
                newdata=data.frame(age=rv$userage,
                                   credit_history=rv$usercredithist,
                                   credit_amount=rv$usercredamt,
                                   installment_commitment=rv$usercommit))
    })
    
    output$text1 <- renderText({
        paste("Input cred hist is :",randpred())
    })