I am trying to build Shiny App that does sentiment analysis. I have the code that works fine when i execute the script normally where Rstudio is importing the data from email.csv file. This file contains only 2 columns ( SentTo and RawText) and the text i am analyzing is located in B2 cell.
Once i run the code below i get nice chart that measure the sentiment.
library(readr)
library("ggplot2")
library('syuzhet')
Emails <- read_csv("C:/email.csv")
d<-get_nrc_sentiment(Emails$RawText)
td<-data.frame(t(d))
td_new <- data.frame(rowSums(td[1:14]))
names(td_new)[1] <- "count"
td_new <- cbind("sentiment" = rownames(td_new), td_new)
rownames(td_new) <- NULL
td_new2<-td_new[1:8,]
qplot(sentiment, data=td_new2, weight=count,
geom="bar",fill=sentiment)+ggtitle("Email sentiments")
Now what i am trying to do is to modify this code a bit and build the Shiny application by doing next:
ui.R
# Adding the Imput text field to the app
shinyUI(fluidPage(
textAreaInput("UserInput", "Caption", "Please Enter Your Text", width =
"500px", height = "300px"),
mainPanel(
plotOutput("distPlot"))
))
Server.R
library(shiny)
library(syuzhet)
library(ggplot2)
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
Emails <- input$UserInput
d<-get_nrc_sentiment(Emails)
td<-data.frame(t(d))
td_new <- data.frame(rowSums(td[1:14]))
names(td_new)[1] <- "count"
td_new <- cbind("sentiment" = rownames(td_new), td_new)
rownames(td_new) <- NULL
td_new2<-td_new[1:8,]
qplot(sentiment, data=td_new2, weight=count,
geom="bar",fill=sentiment)+ggtitle("Email sentiments")
})
})
After i run the app i get this error:
So ti builds the app but even when i paste some text in to the field it seems that the code i am using in server.R part is not doing what it needs to do.
If i replace the line in server.R part (Emails <- input$UserInput) with (Emails <- read_csv("C:/email.csv"))
than it works fine. This tells me that the issue is within the way i am passing the text to the Emails. Through the input form its text through the csv file it is a second row and second column that contains the data. The code that follows i think its looking that specific format.
Anybody has suggestion on how to modify this to make it work?
Thank you in advance.
I believe the issue is in line:
td_new <- data.frame(rowSums(td[1:14]))
If I change it to the following, it works for me:
td_new <- data.frame(rowSums(td))
I'm not sure why you had the 1:14 index in there, but I don't see what it does.
Before plotting in shiny, first have it output the user input so that you understand what is being passed to the next step. verbatimTextOutput('input$UserInput') and verbatimTextOutput('dput(input$UserInput)'). I'm guessing this will be a character vector of length 1.
Now, go back to your code outside of shiny and pass it this same input, formatted exactly the same. Right now your code that works is getting a data.frame from a csv file and passed a column, which would be a character vector.
Once you get it working outside of shiny, using the input as parsed by shiny, the fixes to make your shiny app work should be clear.
Related
I webscraped 2 tables (A and B). Then I merge them by rows (rbind). When I launch it, everything is ok. When I wanna use it in shiny app there is something wrong. Below structure of tables and what shiny shows. Any suggestion? Where could be the problem? Unfortunatelly, I can not show the code, because this is for my thesis. I would be very grateful for your help.
As you can see the problem is with third column. B table has all rows with NA. After merge, all data from A table has also NA.
In shiny table is showed by renderTable.
Structure of tables A and B
I have no answer for your question, but I would like to write something and there is not enough space for this in comment section, so I will write this as answer and eventually delete later. So - I rather believe that there is something wrong with your code which you use inside shiny and would like to check this with your help. I assume you need some help with debugging, so I will post a code below:
library(shiny)
ui <- fluidPage(
tableOutput("table")
)
server <- function(input, output, session) {
my_df <- reactive({
data.frame(a = c(1, 2, 3),
b = c(4, 5, 6))
})
output$table <- renderTable({
my_df()
browser()
})
}
shinyApp(ui, server)
In the code above I have made one output (table output) and - on the server side in reactive - I'm creating data.frame. Then I use this reactive function inside my output (output$plot). However, the last line inside output$plot is function browser() which is used for debugging. You can try my code in your console and see that when you run shiny app, it immediately moving back to console (but this is "dubugging state", so console looks a little different, for example there is a button "stop" with red square which can be use to close debugging state). Please run my shiny app and when you will be back in the console, in the debugging state, type my_df() to see the data.frame object. Could you please do the same with your shiny app? I mean, could you use browser() function on the last line in your renderTable? And come back and tell if the last column contains only NA or not when displayed in the console? If not, then I would say that you are doing something different in Shiny than manually with your tables.
I've been working on an R shiny app that is supposed to take a user-uploaded .csv file, do a bunch of manipulations/calculations to that data, and then spit out some graphs. I am completely new to shiny, however, and am very lost. I've tried to look this up, but most results I found take the data and directly show it in a graph. So far I've tried this (code is taken from here):
UI:
ui <- fluidPage(
fileInput("userfile", "Choose CSV File", multiple = TRUE,
accept=c("text/csv","text/comma-separated-values,text/plain",".csv")),
# etc.
Server:
server <- function(input,output){
df <- read.csv(input$userfile$datapath)
# some manipulation, such as adding a new column, for example:
df$timestwo <- 2 * df$column1
}
Is df in the Server code supposed to be the dataframe that was read in from the user-uploaded file? If not, how can I create a dataframe that is able to go through several changes, before making a graph? When I try to run my code I get "Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer." Thanks!
Edit to add: all the data manipulation I wanted to do worked with my sample dataset, but not the user-input one I tried out (which was the exact same data).
I'm new to Shiny and am trying to run an app using data from an excel file. Seems like it should be simple, but can't figure it out. there's load of info out there on more complex tasks (uploading files interactively, where you specify columns, file location etc) - but all I want is an app that uses data from a single excel file that has loaded in the background.
Similar questions have been asked before (Uploading csv file to shinyApps.io and R Shiny read csv file) but I didn't get a satistactory answer from them.
I have my excel file saved in the same directory as the app.R file, in a folder named 'data'. And I read it into the server part of my script like this:
server <- function(input, output){
# Read in data
myDF <- read_excel('data/MyShinyData.xlsx')
When I run the app.R file to test the app, it works fine. But when I publish it to the Shiny website using shinyapps::deployApp('pathToWorkingDirectory') I get a grayed out version of the app that has no interactivity. The app also publishes to the website fine if I simulate the data within the app.R file (the excel file is just this simulated data, written to excel with write.xlsx) - its only when I take out the code for simulating the data and replace it with the read_excel command that it stops working. I've also tried with a .csv file instead of .xlsx, but same problem.
I've copied the full code from the app.R file below.
What am I doing wrong? Thanks for your help.
library('ggplot2')
library('shiny')
library('psych')
library('readxl')
#===============
#This code makes a histogram, a coplot, and a prediction for species richness ('SpNat') given Forest cover ('NBT').
#===============
m1 <- lm(SpNat ~ NBT, data=myDF) #For prediction. best to create all non-reactive [ie non-updating] code outside the app, so it doesn't have to run every time.
#==========
# ui section
#==========
ui <- fluidPage(
### MAKING A TITLE
titlePanel("Dashboard based on excel data"),
### DIVIDING INPUTS TO SIDEBAR VS MAIN PANELS:
sidebarLayout(
sidebarPanel( #everything nested in here will go in sidebar
#dropdown input for coplot:
tags$h3('Select coplot variables'), #heading
selectInput(inputId='choiceX', label='Choose X variable',
choices=c('Species richness'='SpNat', 'Forest cover'='NBT', 'Pest control'='PC')), #***Choices are concatenated text strings.
selectInput(inputId='choiceY', label='Choose Y variable',
choices=c('Species richness'='SpNat', 'Forest cover'='NBT', 'Pest control'='PC')),
selectInput(inputId='choiceZ', label='Choose conditioning variable',
choices=c('Species richness'='SpNat', 'Forest cover'='NBT', 'Pest control'='PC')),
#checkbox input for pairs plots:
tags$h3('Select variables for pairs plots'), #heading
checkboxGroupInput(inputId='vars', label='Choose at least two variables for pairs plot',
selected=c('SpNat', 'NBT', 'PC'), #'determines which vars start off checked. Important for pairs, cos <2 and plot wont work.
choices=c('Species richness'='SpNat', 'Forest cover'='NBT', 'Pest control'='PC')), #***Server receives input as a single concatenated text
#slider input for prediction:
tags$h3('Predicting forest cover'), #heading
sliderInput(inputId='num',label='Pick a forest cover level', value=10, min=1, max=100)),
mainPanel( #everything nested in here will go in main panel
#specify output for app, including headings:
tags$h3('Coplot:'),
plotOutput(outputId='coplot'),
tags$h3('Histogram:'),
plotOutput(outputId='pairs'),
tags$h3('Predicted species richness:'),
verbatimTextOutput('prediction'))))
#==========
# server section
#==========
server <- function(input, output){
# Read in data
myDF <- read_excel('data/MyShinyData.xlsx') #don't need full path
myDF$PC <- as.factor(myDF$PC)
myDF <- select(myDF, SpNat, NBT, PC)
#create output object, and name it so it corresponds to the ui output function ID, plus use the ui input ID to create it:
output$coplot <- renderPlot(
ggplot(myDF, aes_string(input$choiceX, input$choiceY, col=input$choiceZ)) + geom_point()) #note use of aes_string to allow inputID use direct.
output$pairs <- renderPlot({
pairs.panels(subset(myDF, select=input$vars))})
output$prediction <- renderPrint({
newData <- data.frame(NBT=input$num)
cat(predict(m1, newdata = newData))
})
}
#==========
# and stitch together
#==========
shinyApp(ui=ui, server=server)
Figured it out. I had two problems:
(1) I had copied the app into a new folder prior to publishing, so the working directory had changed - needed to reset to the folder containing my app.R file prior to running shinyapps::deployApp.
(2) a couple of packages required by my app load automatically into my R console (I've made changes to my .Rprofile file). So while I didn't need to load these to run the app locally, I did to publish it online.
Both pretty dumb mistakes, but you live and learn.
I have built a shiny application which is located at the URL below.
https://hdoran.shinyapps.io/openAnalysis/
On the tab called "Choose CrossFit Open Data" I have a textInput() function that calls a function that uses grep(), which is used to find names in a data frame.
The first time the program loads and a name is entered, the search seemingly occurs quickly and names are returned. However, when I delete the name and type a second name, the search is seemingly very slow.
Is there something I can do to optimize this so that is performs quickly always?
I'm still quite new at shiny and am not sure if somehow making this a reactive expression would help. If so, I'm not quite sure how.
Thanks in advance.
The relevant portion of code in the ui.R file
textInput("name", label = 'Enter an athlete name and find your scores',
value = "Enter Name Here")
and the relevant portion of code in the server.R file is
output$myScores <- renderPrint({
df <- filedata()
df[grep(input$name, df$Competitor),]
})
And this portion is also in the ui.R file (though I'm not sure it is relevant to the problem)
verbatimTextOutput("myScores"),
If I understand your goal correctly, you want to give the user the ability to select an input variable based on searching a the competitor column of the dataframe called by filedata()? If so, selectizeInput() is what you are looking for, using server-side selection as outlined here.
Adapted to the code you provided:
ui.r
selectizeInput("name", choices = NULL, multiple = FALSE)
server.r
updateSelectizeInput(session, "name", choices = filedata()$competitor, server = TRUE)
output$myScores <- renderPrint({
df <- filedata()
subset(df, competitor==input$name)
})
I am new to Shiny and trying to build a more accessible input and output for a function I built. I am giving this to people that don't run R so trying to build something that runs my functions in the background and then spits out the answer.
I am having some trouble getting everything in the way that I want it unfortunately and dealing with a bunch of errors. However, here is my more pointed question:
The actual function that I want to run takes a name (in quotations as "Last,First") and a number.
PredH("Last,First",650)
So I want a shiny application that takes a name input and a number input that then runs this program and then spits back out a data table with my answer. So a couple of questions.
How do I get it in the right form to input into my equation on the server side script, do I need to return it in the function so it can be accessed using a function$table type access? (Right now I am just printing using cat() function in the console for the function but know that may not be usable for this type of application.
I want to return a dataframe that can be gotten at PredH14$table. How do I go about building that shiny?
Here is my code so far:
UI:
library(shiny)
shinyUI(pageWithSidebar(
# Application title
headerPanel("Miles Per Gallon"),
# Sidebar with controls to select the variable to plot against mpg
# and to specify whether outliers should be included
sidebarPanel(
textInput("playername", "Player Name (Last,First):", "Patch,Trevor"),
radioButtons("type", "Type:",
list("Pitcher" = "P",
"Hitter" = "H"
)),
numericInput("PAIP", "PA/IP:", 550),
submitButton("Run Comparables")
),
mainPanel(
textOutput("name")
)
Server:
library(shiny)
shinyServer(function(input, output) {
sliderValues <- reactive({
data.frame(
Name = c("name", "PA"),
Value = c(as.character(playername),
PAIP),
stringsAsFactors=FALSE)
})
name=input[1,2]
PAIP=input[2,2]
testing <- function(name,PAIP){
a=paste(name,PAIP)
return(a) }
output$name=renderText(testing$a)
})
I am not quite sure I understood your question 100% but I clearly see you are wondering how to pass the input of the UI into the server and maybe, the other way back.
In your server code, clearly you are not getting any input from the UI. Basically you have created three input variables in your ui.R:
1. input$playername
2. input$type
3. input$PAIP
And one output:
1. output$name
Just let you know, the function sliderValues <- reactive(..) is called every time there is any input from the input... like people click the dropdown list or people modifies words in the text box.
You can even get started without the submit button just to get started. But the existence of the submit button actually makes everything easier. Create a submit button for an input form. Forms that include a submit button do not automatically update their outputs when inputs change, rather they wait until the user explicitly clicks the submit button.
So you can put your code in a way similar like this:
# server.R
library(shiny)
shinyServer(function(input, output) {
sliderValues <- reactive({
result <- ... input$playername ... input$type ... input$PAIP
return(result)
})
output$name <- renderPlot/renderText (... sliderValues...)
})
# ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("Miles Per Gallon"),
sidebarPanel(
textInput("playername" ... ),
radioButtons("type" ... ),
numericInput("PAIP" ... ),
submitButton("...")
),
mainPanel(
textOutput/plotOutput...("name")
)
))
In the end, check out the shiny example that might be what you want.
library(shiny)
runExample('07_widgets')