Update handsontable by editing table and/or eventReactive
You could store the data in a reactiveValues
and have two observers updating it; one if the button is clicked, one if the table is edited by hand.
In your output$table
and output$result
, you then just need to use the data that is in the reactiveValues
. Here's an example (same ui.R
as you posted):
server <- function(input,output,session)({
values <- reactiveValues(data=as.data.frame(runif(2)))
observe({
input$recalc
values$data <- as.data.frame(runif(2))
})
observe({
if(!is.null(input$table))
values$data <- hot_to_r(input$table)
})
output$table <- renderRHandsontable({
rhandsontable(values$data)
})
output$result <- renderText({
sum(values$data)
})
})
Rhsiny: Automatically update an output object based on updated rhandsontable object
Please read this. You can access the rhandsontable params via input$my_id
. To get the current data use input$my_id$params$data.
Here is what I think you are after:
library(shiny)
library(rhandsontable)
ui <- fluidPage(rHandsontableOutput("contents"),
tableOutput("test_table"),
tableOutput("test_table_subset"))
server <- function(input, output) {
# dummy data
x = c('A', 'A', 'A', 'B', 'B', 'C')
y = c('G1', 'G1', 'G1', 'G2', 'G2', 'G3')
z = c('100', '200', '300', '400', '500', '600')
b = data.frame('Category' = x,
'Group' = y,
'Total' = z)
# create reactive object to be used in multiple places
test <- reactive({
t <- b # dplyr::filter(b, b$Category %in% input$cat & b$Group %in% input$group)
return(t)
})
output$contents <- renderRHandsontable({
rhandsontable(test())
})
contentsTableDat <- reactive({
req(input$contents)
hot_to_r(input$contents)
})
output$test_table <- renderTable({
contentsTableDat()
})
output$test_table_subset <- renderTable({
contentsTableDat()[1, 3]
})
}
shinyApp(ui = ui, server = server)
Shiny - Editing rhandsontable tables with multiple input and output elements
I think you were almost there. You can, however, not use an input for creating a reactive value. But this is anyways not eneded and you can initiate it with a NULL
.
library(shiny)
library(rhandsontable)
ui <- fluidPage(
numericInput("x", "number of values", 2),
rHandsontableOutput('table'),
textOutput('result'),
plotOutput('plot'),
actionButton("recalc", "generate new random vals and calculate")
)
server <- function(input,output,session)({
values <- reactiveValues(data = NULL) ## assign it with NULL
## button press resets now the data frame
observeEvent(input$recalc, {
values$data$x <- 0
})
## changes in numericInput sets all (!) new values
observe({
req(input$x)
values$data <- data.frame(x = runif(input$x))
})
observe({
if(!is.null(input$table))
values$data <- hot_to_r(input$table)
})
output$table <- renderRHandsontable({
req(values$data)
rhandsontable(values$data)
})
output$result <- renderText({
req(values$data)
sum(values$data)
})
output$plot <- renderPlot({
req(values$data)
barplot(values$data$x)
})
})
shinyApp(ui = ui, server = server)
How can I update plot from rhandsontable with uploaded data, without clicking into the table first?
In the end I did manage to get this to work by storing the data in reactiveValues
and using a couple of observers. I believe that the eager evaluation of these observers was the key.
New code:
library(shiny)
library(rhandsontable)
empty_mat = matrix(1,nrow = 3, ncol = 1)
curr_names = c("EUR","GBP","CAD")
empty_dat = cbind.data.frame(curr_names,empty_mat)
names(empty_dat) = c("Currency","Values")
ui = fluidPage(sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose CSV File'),
rHandsontableOutput('contents'),
actionButton("go", "Plot Update")
),
mainPanel(
plotOutput("plot1")
)
))
server = function(input, output) {
indat <- reactiveValues(data=empty_dat)
observe({
inFile = input$file1
if (is.null(inFile))
return(NULL)
data1 = read.csv(inFile$datapath)
indat$data <- data1
})
observe({
if(!is.null(input$contents))
indat$data <- hot_to_r(input$contents)
})
output$contents <- renderRHandsontable({
rhandsontable(indat$data)
})
portfoliovals <- eventReactive(input$go, {
return(indat$data[,2])
})
output$plot1 <- renderPlot({
plot(portfoliovals()~c(1,2,3),type = "l")
})
}
shinyApp(ui, server)
R shiny: different behaviours of observeEvent and eventReactive
It's because edits()
isn't called thereafter, so shiny
thinks you don't need it, hence no reason to do any work on it, you need to add where it should go or what you want to do with it:
library(shiny)
ui <- fluidPage(
rhandsontable::rHandsontableOutput(
outputId = "data")
)
server <- function(input, output, session) {
data <- data.frame(a = 1, b = 2, c = 3)
output$data <- rhandsontable::renderRHandsontable({
rhandsontable::rhandsontable(
selectCallback = TRUE,
data = data)
})
observeEvent(input$data$changes$changes, {
print("ping")
})
edits <- eventReactive(input$data$changes$changes, {
print("pong")
})
observe({
edits()
})
}
shinyApp(ui = ui, server = server)
User input in DataTable used for recalculation and update of column in Shiny
I couldn't fully understand your code so I've myself produced another reproducible example based on a bunch of other answers especially this one.
library(shiny)
library(data.table)
library(rhandsontable)
DF = data.frame(num = 1:10, qty = rep(0,10), total = 1:10,
stringsAsFactors = FALSE)
#DF = rbind(DF, c(0,0,0))
ui = fluidPage(
titlePanel("Reactive Table "),
fluidRow(box(rHandsontableOutput("table", height = 400)))
)
server = function(input, output) {
data <- reactiveValues(df=DF)
observe({
input$recalc
data$df <- as.data.frame(DF)
})
observe({
if(!is.null(input$table))
data$df <- hot_to_r(input$table)
})
output$table <- renderRHandsontable({
rhandsontable(data$df)
})
output$table <- renderRHandsontable({
data$df$total <- data$df$num * data$df$qty
print(sum(data$df$num*data$df$price) )
rhandsontable(data$df, selectCallback = TRUE)
})
}
shinyApp(ui, server)
The very first idea is to use rhandsontable
which is specifically for this kind of purpose.
Related Topics
How to Return Number of Decimal Places in R
Shift Values in Single Column of Dataframe Up
Count Observations Greater Than a Particular Value
Find Rows in a Data Frame Where Two Columns Are Equal
R Fuzzy String Match to Return Specific Column Based on Matched String
Lapply-Ing with the "$" Function
Adding X and Y Axis Labels in Ggplot2
Apply a Function to a Subset of Data.Table Columns, by Column-Indices Instead of Name
R Function for Returning All Factors
Converting a List of Data Frames into Individual Data Frames in R
How to Make Variable Bar Widths in Ggplot2 Not Overlap or Gap
Reverse Datetime (Posixct Data) Axis in Ggplot
How to Spread or Cast Multiple Values in R
How to Plot Multiple Stacked Histograms Together in R