由于反应性错误,闪亮的 RStudio 应用程序无法正常工作
Posted
技术标签:
【中文标题】由于反应性错误,闪亮的 RStudio 应用程序无法正常工作【英文标题】:Shiny RStudio app not working due to reactive error 【发布时间】:2020-07-09 09:29:31 【问题描述】:运行应用程序时出现以下错误:
.getReactiveEnvironment()$currentContext() 中的错误: 如果没有活动的反应上下文,则不允许操作。 (你试图做一些只能在反应式表达式或观察者内部完成的事情。)
我第一次尝试了闪亮的应用程序,所以我可能会错过一些我无法弄清楚的关键方面。如果有人可以提供帮助,将不胜感激。
这是我制作的代码:
用户界面:
library(shiny)
shinyUI(pageWithSidebar(
headerPanel(h1('Sentiment Analyzer for .txt Files'),
windowTitle = "Sentiment Analysis"),
# Getting User Inputs
sidebarPanel(
fileInput("fileInput","Please Upload the File"),
textInput("findPhr5ase", "Enter data to be searched"),
submitButton('Analyze')
),
mainPanel(
sidebarPanel(
verbatimTextOutput("file_Health1")
),
sidebarPanel(
textOutput("file_Health2")
),
sidebarPanel(
textOutput("search_Result1")
),
sidebarPanel(
verbatimTextOutput("search_Result2")
),
sidebarPanel(
verbatimTextOutput("search_Result3")
),
sidebarPanel(
wordcloud2Output("sentimentCloud", width = "100%", height = "400px")
),
sidebarPanel(
plotOutput("sentiment_Analysis", width = "40%", height = "200px")
),
sidebarPanel(
plotOutput("topSentiments", width = "40%", height = "200px")
),
sidebarPanel(
dataTableOutput("sentimentScores")
)
)
)
)
服务器:
shinyServer <- function(input, output)
observeEvent(input$analysis,
#Function to read file
searchText <- reactive(renderText(input$findPhrase))
#fileType <- renderText(input$selectType)
read_data_from_file <- function ()
text <- reactive(readtext(input$fileInput))
text <- toString(text[,2])
text<- gsub("\n", "", text)
text <- gsub("[\r\n]", "", text)
return(text)
check_data <- function ()
if (is.null(read_data_from_file()) || is.null(searchText))
return("File or Search Text is empty")
else
return("Starting to analyze file")
output$file_Health1 <- renderPrint(check_data())
#WORD COUNT
output$file_Health2 <- renderText(sapply(read_data_from_file(),stri_stats_latex)['Words',])
#Function to clean the text file
clean_data <- function(text)
#Remove NA values
NAindices = which(is.na(text))
if (is.numeric(NAindices) & length(NAindices) > 0)
text <- text[-c(NAindices)]
#Remove single letters and hyphen
text <- gsub(pattern = "\\b[A-z]\\b1", replace = " ", text)
text <- gsub(pattern = "[-]", replace = " ", text)
#Conversion to corpus
docs <- Corpus(VectorSource(text))
#Cleaning the corpus
docs <- tm_map(docs, content_transformer(tolower))
docs <- tm_map(docs, removeNumbers)
#Remove Stopwords
docs <- tm_map(docs, removeWords, stopwords("english"))
docs <- tm_map(docs, removeWords, c("don", "s", "t"))
docs <- tm_map(docs, removePunctuation)
docs <- tm_map(docs, stripWhitespace)
#Rewriting as text file
writeCorpus(docs, filenames = "clean.txt")
#Reading cleaned text file
text1 <- readtext("clean.txt")
text1 <- toString(text1[,2])
return(text1)
#Function to tokenize the words
tokenize <- function(text)
words = tokenize_words(text)
return (words)
#Hashmap function to get frequency of all words
get_freq_map <- function(words)
hashmap <- hashmap("character")
for(word in words)
hashmap[word] <- 0
for(word in words)
hashmap[word] <- as.numeric(hashmap[word]) + 1
return (hashmap)
#Calling the functions
text2 = tokenize(clean_data(read_data_from_file()))
freq_map = get_freq_map(text2[[1]])
#Function to find frequency of the word given as input
search_keyword_freq <- function(X)
return (freq_map[X])
#Word count Frequency function
output$search_Result1 <-renderText(search_keyword_freq(searchText))
#Reading text file
text = read_data_from_file()
#Tokeninzing the sentences
sentences <- tokenize_sentences(text)
#Function to create a vector of line numbers where the searched word occurs
line_nums <- vector()
for (i in 1:length(sentences[[1]]))
filtered_sent_words = tokenize(clean_data(sentences[[1]][i]))
sentence_freq_map = get_freq_map(filtered_sent_words[[1]])
freq <- tryCatch(sentence_freq_map[searchText], error = function(e) NULL)
if (!(is.null(freq)))
if (freq > 0)
line_nums <- c(line_nums, i)
#Printing the vector and sentences where the word occurs
output$search_Result2 <- renderPrint(line_nums)
output$search_Result3 <- renderPrint(for (i in 1:length(line_nums))
print(sentences[[1]][line_nums[i]]))
##################################################################
# Word Cloud
##################################################################
# take all the phrases
df_data <- data.frame(text = sapply(docs, as.character), stringsAsFactors = FALSE)
# add an id, from 1 to n
df_data$doc_id <- row.names(df_data)
#Tokenize
tidy_docs <- df_data %>% unnest_tokens(word, text)
par(mar = c(1,1,1,1))
# split all the words and Word Cloud
output$sentimentCloud <- renderWordcloud2(tidy_docs %>%inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = TRUE) %>%acast(word ~ sentiment, value.var = "n", fill = 0) %>%
comparison.cloud(scale=c(4,.3), colors = c("#00B2FF", "red", "#FF0099", "#6600CC"), title.size = 1,
title.colors=c("red","blue"),title.bg.colors=c("grey40","grey70"),max.words = 100),
env = parent.frame(), quoted = FALSE)
####################################################################
# polarity
####################################################################
#calculate polarity on text column by grouping doc_id
df_polarity <- polarity(text.var = df_data$text,
grouping.var = df_data$doc_id,
constrain = TRUE,
polarity.frame = key.pol,
negators = qdapDictionaries::negation.words,
amplifiers = qdapDictionaries::amplification.words,
deamplifiers = qdapDictionaries::deamplification.words)
polarity_score <- scores(df_polarity)
polarity_res <- as.data.frame((counts(df_polarity)))
####################################################################
# sentiment analysis
####################################################################
df_data2 <- df_data$text
data_vec <- as.vector(df_data2)
df_emotion <- get_nrc_sentiment(data_vec)
df_emotion_sub <- df_emotion[c(1:8)]
#get the top emotions for each sentence
df_emotion_sub$top_emotions <- apply(df_emotion_sub[-1], 1, FUN = function(x)
paste(names(head(sort(x[x!=0], decreasing = TRUE), 3)), collapse=", "))
#build the final dataframe containing the results of polarity and sentiment analysis
pos_vector <- as.character(polarity_res$pos.words)
neg_vector <- as.character(polarity_res$neg.words)
neg_words <- polarity_res$neg.words
#creating the final data frame
df_final <- data.frame(
text = df_data$text,
words = polarity_res$wc,
positive_words = pos_vector,
negative_words = neg_vector,
polarity = polarity_score$ave.polarity,
emotions = df_emotion_sub$top_emotions
)
################################################
df_final$Pos_Neg <- ifelse(df_final$polarity > 0,"Positive",
ifelse(df_final$polarity < 0,"Negative","Neutral"))
output$sentiment_Analysis <- renderPlot(ggplot(df_final, aes(x = factor(1), y = polarity)) +
geom_boxplot(width = 0.4, fill = "white") +
geom_jitter(aes(color = Pos_Neg, shape = Pos_Neg),
width = 0.1, size = 1) +
scale_color_manual(values = c("#00AFBB", "#E7B800", "tomato1")) +
labs(x = NULL)) # Remove x axis label
#counting frequencies of emotions
f<-data.frame(table(unlist(strsplit(tolower(df_final$emotions), ", "," ,")))) %>% mutate(Freq = sort(Freq))
#######
bar <- ggplot(data = f) +
geom_bar(
mapping = aes(x = Var1, fill = Freq),
show.legend = TRUE,
width = 1
) +
theme(aspect.ratio = 1) +
labs(x = NULL, y = NULL)
output$topSentiments <- renderPlot(bar + coord_flip())
output$sentimentScores <- renderDataTable(df_final[["text","positive_words","negative_words","polarity"]])
)
感谢您帮我解决这个问题。
【问题讨论】:
请尽量使您的示例最小。尽可能多地删除与问题没有直接关系的代码。最有可能的是,当您将问题缩小时,更容易找到确切的原因。还要确保列出所有依赖项。例如wordcloud2Output
不需要来自shiny
。当我把它拿出来时,它似乎运行没有错误。你传入的是什么文件?是不是上传后才会报错?
我想回应@MrFlick 的评论。这是非常复杂的代码,具有许多功能,因此难以评估。如果这对您来说是新的,我会从 shiny
开始。阅读reactivity。您会发现在observeEvent
中有许多嵌入式函数和output
语句可能不是要走的路,它将决定您将包含哪些reactive
函数。让我们知道这是否有帮助。
【参考方案1】:
你想要做的是用反应调用的服务器函数替换你的函数。像这样的东西。 而不是:
read_data_from_file <- function ()
text <- reactive(readtext(input$fileInput))
text <- toString(text[,2])
text<- gsub("\n", "", text)
text <- gsub("[\r\n]", "", text)
return(text)
check_data <- function ()
if (is.null(read_data_from_file()) || is.null(searchText))
return("File or Search Text is empty")
else
return("Starting to analyze file")
你最好写:
read_data_from_file <- reactve(
text <- reactive(readtext(input$fileInput))
text <- toString(text[,2])
text<- gsub("\n", "", text)
text <- gsub("[\r\n]", "", text)
return(text)
)
check_data <- reactive(
if (is.null(read_data_from_file()) || is.null(searchText() ))
return("File or Search Text is empty")
else
return("Starting to analyze file")
)
请不要在searchText
之后添加()
这是引用反应对象的方式。它们就像没有任何参数的函数。
希望这会有所帮助!
【讨论】:
以上是关于由于反应性错误,闪亮的 RStudio 应用程序无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
闪亮的动态/条件过滤选择多个输入(selectizeInput,多个= TRUE)