Text word count in shiny sentiment analysis app

Hey guys, it's me again. Please I am trying to add the countWords() in my shiny app. Here is my code:

if(interactive()){
library(shiny)
library(shinycustomloader)
library(shinythemes)
library(SentimentAnalysis)
library(textclean)
library(reactable)  
 
ui<-navbarPage(strong("Mavis Analytic"),theme=shinytheme("cerulean"),
               windowTitle="Mavis Analytic",fluid=TRUE,inverse=FALSE,
               tabPanel(strong("Opinion Miner"),
                          sidebarLayout(
                          sidebarPanel(width=3,
                          img(src="logo.jpg",height=130,width=150),
                          h4("Enter your texts in these fields"),
                          actionButton("clear","Clear Fields"),br(),br(),
                          textAreaInput("text","Text Field 1",value="It is a beautiful day"),
                          textAreaInput("texts","Text Field 2",value="I am happy to be here"),
                          textAreaInput("word","Text Field 3",value="Let's have some fun"),
                          textAreaInput("words","Text Field 4",value="It has been a bad day"),
                          textAreaInput("wordy","Text Field 5",value="I dislike clowns"),
                          actionButton("run","Run Analysis"),h5(strong("Word Count:")),textOutput("count")
                        ),mainPanel(h4("The Opinion Miner is a tool for conducting sentiment analysis. It is useful for generating insights from product reviews as well as social media posts."),withLoader(reactableOutput("table"),loader="dnaspin"),downloadButton("download","Download Table"),
                                    selectInput("choice","Select Sentiment Score to Plot",choices=c("QDAP","LoughranM","HarvardIV")),selectInput("color","Select Color",choices=c("Blue","Red","Green","Yellow","Purple")),
                                    withLoader(plotOutput("plot",height=400,width=400),loader="dnaspin"),withLoader(plotOutput("graph",height=400,width=400),loader="dnaspin")))),
               tabPanel(strong("Financial Ratios Calculator")),
               navbarMenu(strong("More"),
               tabPanel(strong("Graphs and Charts")),
               tabPanel(strong("Tables")))
  
)
server<-function(input,output,session){
      observeEvent(input$clear,{
      updateTextAreaInput(session,"text",value="")
      updateTextAreaInput(session,"texts",value="")
      updateTextAreaInput(session,"word",value="")
      updateTextAreaInput(session,"words",value="")
      updateTextAreaInput(session,"wordy",value="")
      
     
    })
  
  tables<-reactive({
    data.frame(QDAP,LoughranM,HarvardIV)
    })
    
  output$download<-downloadHandler(
    filename=function(){
      paste("table",".csv",sep="")
    },
    content=function(file){
      write.csv(tables(),file)
    }
  )
  output$table<-renderReactable({
    
      reactable(tables(),searchable=TRUE,selection="multiple",bordered=TRUE,defaultColDef=colDef(
      align="center",
      headerStyle=list(background="#5dade2"),
      style=function(value){
        if(value>0){color<-"#27ae60"}
        else if(value<0){color<-"#e74c3c"}
        else{color<-"#5dade2"}
        list(color=color,fontWeight="bold")
      }),
      highlight=TRUE,outlined=TRUE,striped=TRUE,compact=TRUE,onClick="select")
   
  })
  
  output$count<-renderText({
    as.numeric(word.count())
  })
  
  output$plot<-renderPlot({
    data<-switch(input$choice,
        "QDAP"=QDAP,
        "LoughranM"=LoughranM,
        "HarvardIV"=HarvardIV)
    color<-switch(input$color,
                  "Blue"="#5dade2",
                  "Red"="#e74c3c",
                  "Green"="#1abc9c",
                  "Yellow"="#f7dc6f",
                  "Purple"="#a569bd")
      
    barplot(data,col=color,border="white",xlab="Texts",ylab="Sentiment Scores",main="Bar Plot of Sentiment Scores")
    
  })
  output$graph<-renderPlot({
    data<-switch(input$choice,
                 "QDAP"=QDAP,
                 "LoughranM"=LoughranM,
                 "HarvardIV"=HarvardIV)
    plotSentiment(data)
  })
    Analyze<-reactive(
    analyzeSentiment(
    replace_symbol(
    replace_number(
      replace_ordinal(
            doc<-c(input$text,input$texts,input$word,input$words,input$wordy))))))
  isolate_Analyze<-isolate(Analyze())
  QDAP<-isolate_Analyze$SentimentQDAP
  LoughranM<-isolate_Analyze$SentimentLM
  HarvardIV<-isolate_Analyze$SentimentGI
  
  word.count<-reactive({countWords(doc)})
}
}
 
shinyApp(ui=ui,server=server)

I made it into a reactive function, but I keep getting this error message:

Warning: Error in countWords: object 'doc' not found
  114: countWords
  113: <reactive:word.count> [C:/Users/Idiaye/Documents/Analytic/Analytic.R#40]
   97: word.count
   96: renderText [C:/Users/Idiaye/Documents/Analytic/Analytic.R#69]
   95: func
   82: origRenderFunc
   81: output$count
    1: runApp

Please, I need your help. Thanks

I get lots of errors. The following objects are missing:

SnowballC
QDAP
word.count

Hi @iFeanyi. The problem is just like your last question. The doc value just exists within the reactive Analyze but not public. You may create the reactive named doc as the following.

  doc <- reactive(c(input$text,
                    input$texts,
                    input$word,
                    input$words,
                    input$wordy))
  
  Analyze <- reactive(analyzeSentiment(replace_symbol(replace_number(
    replace_ordinal(
      doc()
    )
  ))))
  word.count <- reactive({
    countWords(doc())
  })
1 Like

Hi Mr Woodward. Thanks for taking out time to look into my problem. So what do you suggest I do?

Hi @raytong, thanks again for trying to help me. I did as you suggested, but I am getting a new error message, telling me 'QDAP' is missing.

@iFeanyi. My code like this and work properly. Are you missing the blanket of doc in Analyze?

library(shiny)
library(shinycustomloader)
library(shinythemes)
library(SentimentAnalysis)
library(textclean)
library(reactable)

ui <-
  navbarPage(
    strong("Mavis Analytic"),
    theme = shinytheme("cerulean"),
    windowTitle = "Mavis Analytic",
    fluid = TRUE,
    inverse = FALSE,
    tabPanel(
      strong("Opinion Miner"),
      sidebarLayout(
        sidebarPanel(
          width = 3,
          img(
            src = "logo.jpg",
            height = 130,
            width = 150
          ),
          h4("Enter your texts in these fields"),
          actionButton("clear", "Clear Fields"),
          br(),
          br(),
          textAreaInput("text", "Text Field 1", value =
                          "It is a beautiful day"),
          textAreaInput("texts", "Text Field 2", value =
                          "I am happy to be here"),
          textAreaInput("word", "Text Field 3", value =
                          "Let's have some fun"),
          textAreaInput("words", "Text Field 4", value =
                          "It has been a bad day"),
          textAreaInput("wordy", "Text Field 5", value =
                          "I dislike clowns"),
          actionButton("run", "Run Analysis"),
          h5(strong("Word Count:")),
          textOutput("count")
        ),
        mainPanel(
          h4(
            "The Opinion Miner is a tool for conducting sentiment analysis. It is useful for generating insights from product reviews as well as social media posts."
          ),
          withLoader(reactableOutput("table"), loader = "dnaspin"),
          downloadButton("download", "Download Table"),
          selectInput(
            "choice",
            "Select Sentiment Score to Plot",
            choices = c("QDAP", "LoughranM", "HarvardIV")
          ),
          selectInput(
            "color",
            "Select Color",
            choices = c("Blue", "Red", "Green", "Yellow", "Purple")
          ),
          withLoader(plotOutput(
            "plot", height = 400, width = 400
          ), loader = "dnaspin"),
          withLoader(plotOutput(
            "graph", height = 400, width = 400
          ), loader = "dnaspin")
        )
      )
    ),
    tabPanel(strong("Financial Ratios Calculator")),
    navbarMenu(strong("More"),
               tabPanel(strong("Graphs and Charts")),
               tabPanel(strong("Tables")))
    
  )
server <- function(input, output, session) {
  observeEvent(input$clear, {
    updateTextAreaInput(session, "text", value = "")
    updateTextAreaInput(session, "texts", value = "")
    updateTextAreaInput(session, "word", value = "")
    updateTextAreaInput(session, "words", value = "")
    updateTextAreaInput(session, "wordy", value = "")
    
    
  })
  
  tables <- reactive({
    data.frame(QDAP, LoughranM, HarvardIV)
  })
  
  output$download <- downloadHandler(
    filename = function() {
      paste("table", ".csv", sep = "")
    },
    content = function(file) {
      write.csv(tables(), file)
    }
  )
  output$table <- renderReactable({
    reactable(
      tables(),
      searchable = TRUE,
      selection = "multiple",
      bordered = TRUE,
      defaultColDef = colDef(
        align = "center",
        headerStyle = list(background = "#5dade2"),
        style = function(value) {
          if (value > 0) {
            color <- "#27ae60"
          }
          else if (value < 0) {
            color <- "#e74c3c"
          }
          else{
            color <- "#5dade2"
          }
          list(color = color, fontWeight = "bold")
        }
      ),
      highlight = TRUE,
      outlined = TRUE,
      striped = TRUE,
      compact = TRUE,
      onClick = "select"
    )
    
  })
  
  output$count <- renderText({
    as.numeric(word.count())
  })
  
  output$plot <- renderPlot({
    data <- switch(
      input$choice,
      "QDAP" = QDAP,
      "LoughranM" = LoughranM,
      "HarvardIV" = HarvardIV
    )
    color <- switch(
      input$color,
      "Blue" = "#5dade2",
      "Red" = "#e74c3c",
      "Green" = "#1abc9c",
      "Yellow" = "#f7dc6f",
      "Purple" = "#a569bd"
    )
    
    barplot(
      data,
      col = color,
      border = "white",
      xlab = "Texts",
      ylab = "Sentiment Scores",
      main = "Bar Plot of Sentiment Scores"
    )
    
  })
  output$graph <- renderPlot({
    data <- switch(
      input$choice,
      "QDAP" = QDAP,
      "LoughranM" = LoughranM,
      "HarvardIV" = HarvardIV
    )
    plotSentiment(data)
  })
  doc <- reactive(c(input$text,
                    input$texts,
                    input$word,
                    input$words,
                    input$wordy))
  Analyze <- reactive(analyzeSentiment(replace_symbol(replace_number(
    replace_ordinal(
      doc()
    )
  ))))
  isolate_Analyze <- isolate(Analyze())
  QDAP <- isolate_Analyze$SentimentQDAP
  LoughranM <- isolate_Analyze$SentimentLM
  HarvardIV <- isolate_Analyze$SentimentGI
  
  word.count <- reactive({
    countWords(doc())
  })
}
}

shinyApp(ui = ui, server = server)

Hi @raytong. I am still having error issues. I have done as you suggested. Could it be how I write my reactive functions e.g. reactive({})?

@iFeanyi. The QDAP problem is due to QDAP is not a reactive value. In shiny, if you want to use variable to store value, the variable must be reactive value. The same problem occur in variable isolate_Analysis, LoughranM and HarvardIV. I suggest you create a reactiveValues to store values in the app.

I have resolved the problem. I used the renderTable() function in place of the renderText() function, and this now displays the word count for each text area in a table. Thanks a lot @raytong for your patiently going through my issues and offering good advice.

1 Like