EmbDev.net

Forum: Off Topic R Shiny: Creating factor variables and defining levels


von Tobi M. (tobimarsh43)


Rate this post
useful
not useful
I trying to create a machine learning application with Shiny.

In this application, the user can select the specifications of the input 
variables (via. input widgets) which will be used to give an estimate of 
a response variable. To do this, I have created a data frame from the 
selected inputs and save it locally as a data table.

A problem arises when I load the data table again since this will cause 
all categorical variables to become character variables. I can however 
change these manually with the factor() function and use the levels= 
specification.

The problem is that I don't want to manually do this every time a new 
dataset gets used, since most likely will change the position of the 
categorical variables in the dataset. There will also most likely not be 
the same amount of categorical variables in a new dataset.

The data frame "DATA" is the main dataset that contains the response 
variable in column 1.

The data frame "test" is the data frame constructed from the selected 
inputs, which will be used as the test set for prediction and will 
contain only 1 specified observation. This data frame will always have 
the response variable as the last column in the data frame, due to how 
the data frame is constructed. So the factor variable in DATA[,5] will 
always correspond to the previous column in the test data frame: 
test[,4].

It is the test data frame that needs the factor levels to be specified 
since it doesn't automatically know the number of categories when it 
only contains 1 observation.

test[4] <- factor(test[4], levels = unique(DATA[,5]))

I'm trying to write a code that will apply the factor function on all 
character variables in the dataset and specify the levels no matter the 
position of the character variable in the dataset.

Here is the code I have written so far:
1
library(shiny)
2
library(tidyverse)
3
library(shinythemes)
4
library(data.table)
5
library(RCurl)
6
library(randomForest)
7
library(mlbench)
8
library(janitor)
9
10
11
# Read data
12
DATA <- BostonHousing
13
14
# Rearrange data so the response variable is located in column 1
15
DATA <- DATA[,c(names(BostonHousing)[14],names(BostonHousing)[-14])]
16
17
# Creating a simple RF model
18
model <- randomForest(medv ~ ., data = DATA, ntree = 500, mtry = 4, importance = TRUE)
19
20
21
# UI -------------------------------------------------------------------------
22
ui <- fluidPage(
23
  
24
  sidebarPanel(
25
    
26
    h3("Parameters Selected"),
27
    br(),
28
    tableOutput('show_inputs'),
29
    hr(),
30
    actionButton("submitbutton", label = "calculate", class = "btn btn-primary", icon("calculator")),
31
    hr(),
32
    tableOutput("tabledata")
33
34
    
35
  ), # End sidebarPanel
36
  
37
  mainPanel(
38
    
39
    h3("Input widgets"),
40
    uiOutput("select")
41
    
42
  ) # End mainPanel
43
  
44
) # End UI bracket
45
46
47
48
# Server -------------------------------------------------------------------------
49
server <- function(input, output, session) {
50
  
51
# Create input widgets from dataset  
52
  output$select <- renderUI({
53
    df <- req(DATA)
54
    tagList(map(
55
      names(df[-1]),
56
      ~ ifelse(is.numeric(df[[.]]),
57
               yes = tagList(sliderInput(
58
                 inputId = paste0(.),
59
                 label = .,
60
                 value = mean(df[[.]], na.rm = TRUE),
61
                 min = round(min(df[[.]], na.rm = TRUE),2),
62
                 max = round(max(df[[.]], na.rm = TRUE),2)
63
               )),
64
               no = tagList(selectInput(
65
                 inputId = paste0(.),
66
                 label = .,
67
                 choices = sort(unique(df[[.]])),
68
                 selected = sort(unique(df[[.]]))[1],
69
               ))
70
      )
71
    ))
72
  })
73
  
74
75
# creating dataframe of selected values to be displayed
76
  AllInputs <- reactive({
77
    id_exclude <- c("savebutton","submitbutton")
78
    id_include <- setdiff(names(input), id_exclude)
79
    
80
    if (length(id_include) > 0) {
81
      myvalues <- NULL
82
      for(i in id_include) {
83
        myvalues <- as.data.frame(rbind(myvalues, cbind(i, input[[i]])))
84
        
85
      }
86
      names(myvalues) <- c("Variable", "Selected Value")
87
      myvalues %>% 
88
        slice(match(names(DATA[,-1]), Variable))
89
    }
90
  })
91
92
  
93
# render table of selected values to be displayed
94
  output$show_inputs <- renderTable({
95
    AllInputs()
96
  })
97
  
98
 
99
# Creating a dataframe for calculating a prediction
100
  datasetInput <- reactive({  
101
    
102
    df1 <- data.frame(AllInputs(), stringsAsFactors = FALSE)
103
    input <- transpose(rbind(df1, names(DATA[1])))
104
105
    write.table(input,"input.csv", sep=",", quote = FALSE, row.names = FALSE, col.names = FALSE)
106
    test <- read.csv(paste("input.csv", sep=""), header = TRUE)
107
    
108
    
109
# defining factor levels for factor variables
110
    test[4] <- factor(test[4], levels = unique(DATA[,5])) # <- This line will cause problems if multiple factors in dataset or if different column location
111
   
112
113
# Making the actual prediction and store it in a data.frame     
114
    Prediction <- predict(model,test)
115
    Output <- data.frame("Prediction"=Prediction)
116
    print(format(Output, nsmall=2, big.mark=","))
117
  })
118
  
119
120
# display the prediction when the submit button is pressed
121
  output$tabledata <- renderTable({
122
    if (input$submitbutton>0) { 
123
      isolate(datasetInput()) 
124
    } 
125
  })
126
  
127
  
128
} # End server bracket
129
130
131
132
# ShinyApp -------------------------------------------------------------------------
133
shinyApp(ui, server)

Pursuing ML course - 
https://intellipaat.com/machine-learning-certification-training-course/

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.