I've had some luck with Shiny and R, but I can't get an selectInput function to change the dataframe. I'm probably missing something obvious, but here's my code
require(shiny)
A <- data.frame(x=c(1,2,3),y=c(3,2,1))
B <- data.frame(x=c(1,1,5),y=c(3,5,0))
ui <- fluidPage(
selectInput("df", "Select dataframe", choices = c('A'='A','B'='B'), selected = 'A'),
plotOutput("Plot")
)
server <- function(input, output)
{
df <- reactive({
x <- as.data.frame(input$df)
})
output$Plot <- renderPlot({
df <- df()
plot(x=df$x, y=df$y)
})
}
shinyApp(ui = ui, server = server)
What am I missing?
You cant use as.data.frame and name of df
try to use get
A <- data.frame(x=c(1,2,3),y=c(3,2,1))
B <- data.frame(x=c(1,1,5),y=c(3,5,0))
shinyServer(function(input, output) {
df <- reactive({
x <- get(input$df)
})
output$Plot <- renderPlot({
df <- df()
plot(x=df$x, y=df$y)
})
})
Related
I have a table where the user can change the data, and the updated data will be used for future calculations.
Here is an example of a table, and I want it so that when the table is modified, the necessary information on the main panel will be updated accordingly.
Here is my code:
library(ggplot2)
library(DT)
library(shiny)
ui <- fluidPage(
sidebarLayout(sidebarPanel(
DTOutput("mytable"),
actionButton("update", "Update")
),
mainPanel(
plotOutput("plot"),
verbatimTextOutput("text")
)
)
)
server <- function(input, output, session) {
tab <- reactiveValues(df = {data.frame(
num = 1:5,
x = LETTERS[1:5],
y = c(14,5,8,9,13)
)})
output$mytable <- renderDT({
DT::datatable(tab$df, editable = T, selection = "none")
})
observeEvent(input$update,{
output$plot <- renderPlot({
tab$df %>% ggplot(aes(x,y)) + geom_point()
})
output$text <- renderPrint({
tab$df$x
})
})
}
shinyApp(ui, server)
Try this approach with your server method.
First, add an observeEvent to detect edits/changes to your datatable. When there are, the changes are stored in your tab which is reactive.
Second, if you want an actionbutton to redo the plot and text, then would also make a second reactiveValues rv and observeEvent to store and update them when the button is pressed.
server <- function(input, output, session) {
tab <- reactiveValues(df = {data.frame(
num = 1:5,
x = LETTERS[1:5],
y = c(14,5,8,9,13)
)})
rv <- reactiveValues(
plot = NULL,
text = NULL
)
output$mytable <- renderDT({
DT::datatable(tab$df, editable = T, selection = "none")
})
observeEvent(input$mytable_cell_edit, {
row <- input$mytable_cell_edit$row
clmn <- input$mytable_cell_edit$col
tab$df[row, clmn] <- input$mytable_cell_edit$value
})
observeEvent(input$update,{
rv$text <- tab$df$x
rv$plot <- tab$df %>%
ggplot(aes(x,y)) +
geom_point()
})
output$plot <- renderPlot({
rv$plot
})
output$text <- renderPrint({
rv$text
})
}
I am building a Shiny app and using the code from this question as an example: How to download editable data table in shiny. However, in my code the df <- reactiveVal(dat) does not work, because the dat itself is already a reactive value that comes from an eventReactive({}) function. This is the code I am working with, it works if I define the dat outside of the server, but not when it is created inside the server function of shiny. How do I make a copy of it so that I can show it in a new table (and potentially process further and download in later steps in the app)?
library(shiny)
library(DT)
library(shinyWidgets)
# if the data frame is just an object, it works
#dat <- iris[1:3, ]
ui <- fluidPage( actionBttn(
inputId = "btnProcess",
label = "Process",
size = "sm",
color = "success"
),
DTOutput("my_table"),
DTOutput("table2")
)
server <- function(input, output){
# if the dataframe is a reactive variable, this doesnt work.
dat <- eventReactive(input$btnProcess, {
iris[1:3, ]
})
output[["my_table"]] <- renderDT({
datatable(dat(), editable = "cell")
})
#############################
#### none of these work #####
#############################
#df <- reactiveVal(dat)
#df <- reactiveVal(dat())
#df <- dat()
#df <- dat
observeEvent(input[["my_table_cell_edit"]], {
cell <- input[["my_table_cell_edit"]]
newdf <- df()
newdf[cell$row, cell$col] <- cell$value
df(newdf)
})
output[["table2"]] <- renderDT({
datatable(df())
})
}
shinyApp(ui, server)
Try this
ui <- fluidPage( actionBttn(
inputId = "btnProcess",
label = "Process",
size = "sm",
color = "success"
),
actionBttn(inputId = "reset", label = "Reset", size="sm", color="warning"),
DTOutput("mytable"),
DTOutput("table2")
)
server <- function(input, output){
# if the dataframe is a reactive variable, this doesnt work.
dat <- eventReactive(input$btnProcess, {
iris[1:3, ]
})
mydf <- reactiveValues(data=NULL)
observe({
mydf$data <- dat()
})
output$mytable <- renderDT({
datatable(mydf$data, editable = "cell")
})
observeEvent(input$mytable_cell_edit, {
info = input$mytable_cell_edit
str(info)
i = info$row
j = info$col
v = info$value
mydf$data[i, j] <<- DT::coerceValue(v, mydf$data[i, j])
})
output[["table2"]] <- renderDT({
datatable(mydf$data)
})
observeEvent(input$reset, {
mydf$data <- dat() ## reset it to original data
})
}
shinyApp(ui, server)
I am trying to do something that is quite simple to achieve in R script but I am struggling to replicate when part of a Shiny app. I am reading a file using ‘reactive({})’ (this part in the test code provided below has been replaced with test dataset, lines 13-16). I would like to take variable ‘Species’ entries and assign them to the data frame row names. I have tried two approaches
Inside the “reactive({})” statement, lines 13-16
By creating a new data frame df1, lines 18-20
but both ways don’t work for some reason.
Big thank you in advance!
library(shiny)
library(DT)
library(datasets)
ui <- basicPage("",
DT::dataTableOutput("table"),
verbatimTextOutput("head1"),
verbatimTextOutput("head2")
)
server <- function(input, output, session) {
df <- reactive({
df <- data.frame(v1=c("a", "b"), v2=c(10,20))
# row.names(df) <- df[,1] # THIS DOES NOT WORK
})
df1 <- reactive({ # THIS ALSO DOESN'T WORK
row.names(df()) <- df()[,1]
})
# Show data in a table ----
output$table <- DT::renderDataTable({
datatable(
{df()},
filter = 'top',
class="cell-border stripe",
rownames = TRUE
) # end of datatable
})
output$head1 <- renderPrint({
head(df())
})
output$head2 <- renderPrint({
head(df1())
})
}
shinyApp(ui = ui, server = server)
Try this
library(shiny)
library(DT)
library(datasets)
ui <- basicPage("",
DTOutput("table"),
DTOutput("head1"),
DTOutput("head2")
)
server <- function(input, output, session) {
df <- reactive({
df <- data.frame(v1=c("a", "b"), v2=c(10,20))
row.names(df) <- df[,1] # THIS WORKs
df
})
df1 <- reactive({ # THIS ALSO WORKs
data <- df()
row.names(data) <- df()[,1]
data
})
# Show data in a table ----
output$table <- renderDT({
datatable(
{df()},
filter = 'top',
class="cell-border stripe",
rownames = TRUE
) # end of datatable
})
output$head1 <- renderDT({
head(df())
})
output$head2 <- renderDT({
head(df1())
})
}
shinyApp(ui = ui, server = server)
I am using below code to lean Shiny R , when i run this code, it gives me this error:
Warning: Error in hist.default: 'x' must be numeric
[No stack trace available]
library(shiny)
ui <- fluidPage(
selectInput("Ind","Indipendent Variable",choices = names(mtcars)),
selectInput('Dep',' Dependent Variable',choices = names(mtcars)),
plotOutput("BoxPlot"),
plotOutput('Hist'))
server <- function(input, output, session) {
data1 <- reactive({input$Ind})
data2 <- reactive({input$Dep})
output$BoxPlot <- renderPlot({boxplot(get(data2()) ~ get(data1()) , data=mtcars)})
output$Hist <- renderPlot({hist(get(data1())})
}
shinyApp(ui, server)
any help why would it say so ?
Try not to put everything into 1 line as it doesnt improve readability, you can use Google's R Style Guide if you like.To answer your questions you can access the variable via [[]] like so:
library(shiny)
ui <- fluidPage(
selectInput("Ind","Indipendent Variable",choices = names(mtcars)),
selectInput('Dep',' Dependent Variable',choices = names(mtcars)),
plotOutput("BoxPlot"),
plotOutput('Hist')
)
server <- function(input, output, session) {
data1 <- reactive({
input$Ind
})
data2 <- reactive({
input$Dep
})
output$BoxPlot <- renderPlot({
boxplot(get(data2()) ~ get(data1()) , data=mtcars)
})
output$Hist <- renderPlot({
req(data1())
hist(mtcars[[data1()]])
})
}
shinyApp(ui, server)
In the below toy example I have a data set datapred. The data set are output to an interactive table using rhandsontable. Then I covert it in a new data.frame with hot_to_r. My issue is that when I wnat to use it in my function prediction(), it send me an error message and the application crash. I don't understand why.
I'm french so I converted in english the message :
Error in as.name: the 'pairlist' object can not be automatically converted to a 'symbol' type.
library(shiny)
library(frailtypack)
library(rhandsontable)
data("readmission", package = "frailtypack")
ui <- fluidPage(
titlePanel("prediction"),
mainPanel(
fluidRow(rHandsontableOutput("hot")),
br(),
plotOutput("pred")
)
)
server <- function(input, output) {
newdata <- subset(readmission,select = c("time","event","id","dukes"))
datapred <- newdata[1,]
data <- reactive({
DF = hot_to_r(input$hot)
DF
})
model <- frailtyPenal(Surv(time,event)~cluster(id)+dukes,n.knots=10,
kappa=10000,data=readmission)
predict <- reactive(
prediction(model, data(),t=200,window=seq(50,1900,50),
MC.sample=100))
output$hot <- renderRHandsontable({
rhandsontable(datapred)
})
data <- reactive({
DF = hot_to_r(input$hot)
DF
})
output$pred <- renderPlot({
plot(predict(),conf.bands=TRUE)
})
}
shinyApp(ui = ui, server = server)
You could simply evaluate the data() first, like this. I also added some checks so you don't get other errors during the initialization
library(shiny)
library(frailtypack)
library(rhandsontable)
data("readmission", package = "frailtypack")
ui <- fluidPage(
titlePanel("prediction"),
mainPanel(
fluidRow(rHandsontableOutput("hot")),
br(),
plotOutput("pred")
)
)
server <- function(input, output) {
newdata <- subset(readmission,select = c("time","event","id","dukes"))
datapred <- newdata[1,]
data <- reactive({
hot <- input$hot
if (!is.null(hot)) hot_to_r(hot)
})
model <- frailtyPenal(Surv(time,event)~cluster(id)+dukes,n.knots=10,
kappa=10000,data=readmission)
predict <- reactive({
dat <- data()
if (!is.null(dat)) {
prediction(model, dat,t=200,window=seq(50,1900,50),
MC.sample=100)
}
})
output$hot <- renderRHandsontable({
rhandsontable(datapred)
})
output$pred <- renderPlot({
pred <- predict()
if (!is.null(pred)) plot(pred, conf.bands = TRUE)
})
}
shinyApp(ui = ui, server = server)