发光的应用程序,用于在用户按下“ enter”(输入)时进行反应并表达和绘图

时间:2019-07-19 05:51:49

标签: r twitter shiny analysis reactive

这是一个使用Twitter API分析推文的应用程序 有一个textInput,当前每次输入更改时,服务器都会提取数据,清理数据并更新绘图。 我只希望在用户键入搜索词然后按“ enter”(输入)后才发生这种情况。

我相信可以使用isolate()完成此操作,但是我很茫然。 感谢您的任何帮助,谢谢!

我当前有一个tag $ script,它在最后一次按下用户键时读取。经过测试,初始图显示了当我按Enter键时显示的内容,但是,每当以后更新文本字段时,绘图都会更新,而无需按Enter键。不知道为什么,因为我将代码包含在observe()中,但是我必须了解一些错误。下面是代码,但是如果没有您自己的Twitter API密钥,您将无法完全运行它

library(shiny)
library(ggplot2)
library(readr)
library(rsconnect) # Deploy Shiny App
library(data.table)
library(plotly)
library(tm) # Text mining
library(dplyr)
library(twitteR) # Pull from Twitter API
library(sentimentr) # Sentiment Analysis
library(tidytext)
library(Unicode)
library(RColorBrewer) # Color palletes
library(base64enc)
library(shinyWidgets) 
library(shinycssloaders) # Loading animatiions
library(wordcloud) # Create wordclouds
library(shinyjs) # Calls shinyjs functions

ui <- fluidPage(

  tags$script(' $(document).on("keydown", function (e) {
                                                 Shiny.onInputChange("lastkeypresscode", e.keyCode);
                                                  });'),
fluidRow( 
    column(12,
           h2("Show me analysis on")),
           textInput("search","", value = "cats")),

    )
  ),
fluidRow(
    column(6, plotOutput("wordcloud") %>% withSpinner()),
    column(6, plotlyOutput("sentiment")  %>% withSpinner()

    )
  )

)

server <- function(input, output,session) {

  # Authentication keys to access TWitter's API
  consumerKey <- 'k1WaBd'
  consumerSecret <- 'XFQMKfh'
  accessToken <- '14554'
  accessSecret <- 'ZHDvhGmdh'
  setup_twitter_oauth(consumerKey, consumerSecret, accessToken, accessSecret)

# Get Tweet Data
  rawTweets <- reactive({rawTweets <- searchTwitter(req(input$search), n = 200) })

  # Clean raw Twitter data, returns just the body of tweets w/o links and emojis
  cleanTweets <- function(rawTweets){
    df<- do.call("rbind",lapply(rawTweets,as.data.frame))
    # Remove emojis
    df$text <- sapply(df$text,function(row) iconv(row, "latin1", "ASCII", sub="")) 
    df[, c('isRetweet','id', 'longitude','latitude', 'replyToUID', 'replyToSID', 'replyToSN')] <- NULL
    df <- df[!duplicated(df$text), ] # Remove duplicate tweets
    df <- df[!duplicated(df$screenName), ] # Remove duplicate users

    df$text[df$text == ""] <- NA 
    df$letterCount <- nchar(gsub(" ","",df$text)) 
    df$text[df$letterCount == '0'] <- NA 
    df <- na.omit(df)  
    return (df$text)
  }

  # Holds list of cleaned tweets
  words <- reactive({words <- cleanTweets(rawTweets())
  })

  createCorpus <-function(words){

    # Create a corpus to store word data, from package tm
    corpus <- Corpus(VectorSource(words))
    corpus <- tm_map(corpus, removePunctuation)
    corpus <- tm_map(corpus, content_transformer(tolower))
    corpus <- tm_map(corpus,function(x)removeWords(x,stopwords()))

    return(corpus)
  }

  corpus <- reactive({corpus <- createCorpus(words() )})


  observe({
    if(!is.null(input$lastkeypresscode)) {
      if(input$lastkeypresscode == 13){


        if (is.null(input$search) || input$search == "")
          return()

        output$wordcloud <- renderPlot({
          wordcloud(corpus(), min.freq = 3, scale = c(7, 2), random.order = F, colors = brewer.pal(8,'Dark2'))
        })

        # Sentiment Scoring
        sentiment <- reactive({sentiment <- sentiment_by(words()) })
        emotion <- reactive({emotion <- emotion_by(words() )})

        output$sentiment <- renderPlotly({
          # Count # of tweets in each category
          neutral <- sum(sentiment()$ave_sentiment == "0")
          positive <- sum(sentiment()$ave_sentiment > "0")
          negative <- sum(sentiment()$ave_sentiment < "0")
          feeling <- c('positive', 'negative', 'neutral')
          count <- c(positive,negative,neutral)
          df <- data.frame(feeling,count, stringsAsFactors=FALSE)

          plot_ly(df,labels = ~feeling, values = ~count, type = 'pie', 
                  marker = list(colors = c('#c2fa87', '#ffb39c', '#d1d1c9'))
        })


      }
    }
  })

}

shinyApp(ui = ui, server = server)

2 个答案:

答案 0 :(得分:1)

我尝试使用搜索操作按钮

ui <- fluidPage(
  fluidRow(column(6,
                  h2("Show me analysis on")),
           textInput("keySearch", NULL)),
  column(
    width = 1,
    actionButton("search", "Search"),
    tags$style(
      "#search { color: #fff; background-color: #00557F; margin-top:24px; font-family: 'Candara'; }"
    )
  ),
  fluidRow(
    column(6, plotOutput("wordcloud") %>% withSpinner()),
    column(6, plotlyOutput("sentiment")  %>% withSpinner())
  )
)

server <- function(input, output, session) {
  # Authentication keys to access TWitter's API
  consumerKey <- 'your key'
  consumerSecret <- 'your secret'
  accessToken <- 'your token'
  accessSecret <- 'your secret'
  setup_twitter_oauth(consumerKey, consumerSecret, accessToken, accessSecret)

  # Get Tweet Data
  rawTweets <-
    eventReactive(input$search, {
      searchTwitter(req(input$keySearch), n = 200)
    })

  # Clean raw Twitter data, returns just the body of tweets w/o links and emojis
  cleanTweets <- function(rawTweet) {
    df <- do.call("rbind", lapply(rawTweet, as.data.frame))
    # Remove emojis
    df$text <-
      sapply(df$text, function(row)
        iconv(row, "latin1", "ASCII", sub = ""))
    df[, c(
      'isRetweet',
      'id',
      'longitude',
      'latitude',
      'replyToUID',
      'replyToSID',
      'replyToSN'
    )] <- NULL
    df <- df[!duplicated(df$text),] # Remove duplicate tweets
    df <- df[!duplicated(df$screenName),] # Remove duplicate users

    df$text[df$text == ""] <- NA
    df$letterCount <- nchar(gsub(" ", "", df$text))
    df$text[df$letterCount == '0'] <- NA
    df <- na.omit(df)
    return (df$text)
  }

  # Holds list of cleaned tweets
  words <- reactive({
    words <- cleanTweets(rawTweets())
  })

  createCorpus <- function(words) {
    # Create a corpus to store word data, from package tm
    corpus <- Corpus(VectorSource(words))
    corpus <- tm_map(corpus, removePunctuation)
    corpus <- tm_map(corpus, content_transformer(tolower))
    corpus <- tm_map(corpus, function(x)
      removeWords(x, stopwords()))

    return(corpus)
  }

  corpus <- reactive({
    corpus <- createCorpus(words())
  })


  observeEvent(input$search, {
    output$wordcloud <- renderPlot({
      wordcloud(
        corpus(),
        min.freq = 3,
        scale = c(7, 2),
        random.order = F,
        colors = brewer.pal(8, 'Dark2')
      )
    })

    # Sentiment Scoring
    sentiment <- reactive({
      sentiment <- sentiment_by(words())
    })
    emotion <- reactive({
      emotion <- emotion_by(words())
    })

    output$sentiment <- renderPlotly({
      # Count # of tweets in each category
      neutral <- sum(sentiment()$ave_sentiment == "0")
      positive <- sum(sentiment()$ave_sentiment > "0")
      negative <- sum(sentiment()$ave_sentiment < "0")
      feeling <- c('positive', 'negative', 'neutral')
      count <- c(positive, negative, neutral)
      df <- data.frame(feeling, count, stringsAsFactors = FALSE)

      plot_ly(
        df,
        labels = ~ feeling,
        values = ~ count,
        type = 'pie',
        marker = list(colors = c('#c2fa87', '#ffb39c', '#d1d1c9'))
      )
    })
  })

}

shinyApp(ui = ui, server = server)

答案 1 :(得分:0)

我尚未进行正确的测试,但是您可以尝试使用observeEvent代替如下所示的observer:

observeEvent(req(input$lastkeypresscode==13), {

    if (is.null(input$search) || input$search == "")
      return()

    output$wordcloud <- renderPlot({
      wordcloud(corpus(), min.freq = 3, scale = c(7, 2), random.order = F, colors = brewer.pal(8,'Dark2'))
    })

    # Sentiment Scoring
    sentiment <- reactive({sentiment <- sentiment_by(words()) })
    emotion <- reactive({emotion <- emotion_by(words() )})

    output$sentiment <- renderPlotly({
      # Count # of tweets in each category
      neutral <- sum(sentiment()$ave_sentiment == "0")
      positive <- sum(sentiment()$ave_sentiment > "0")
      negative <- sum(sentiment()$ave_sentiment < "0")
      feeling <- c('positive', 'negative', 'neutral')
      count <- c(positive,negative,neutral)
      df <- data.frame(feeling,count, stringsAsFactors=FALSE)

      plot_ly(df,labels = ~feeling, values = ~count, type = 'pie', 
              marker = list(colors = c('#c2fa87', '#ffb39c', '#d1d1c9'))
    })
})