Caphoon
Caphoon

Reputation: 33

Collecting values from Input

I'm quite new to Shiny and I have a possibly stupid question: I built a flexdashboard which shows the results of a calculation. At first I set the input values manually in the code. The next step would be to enable the dashboard to collect the input values using shiny. It is not reasonable to change the plots and tables instantly but to collect the data first, evaluate them and if they are complete and suitable for the calculation, I would like to recalculate und show the results. I was able to display the Input fields on the sidebar and to initate the check-function. For the purpose of checking if the dataset is complete, I defined a globally accessible data.frame to collect the different values. By using primes I want to check, if a specific part of the calculation can be started; this is part of the check-function as well. But my wish to collect the values in the data.frame is ignored constantly... What is wrong with my code? Here is a simple example of what I'm trying to do (.rmd):

---
title: "example"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
runtime: shiny
---

```{r setup, include=FALSE}
library(flexdashboard)
library(shiny)
library(stringr)
source("ProcessThatValue.R")
generate_VALUEFRAME()
```

Column {data-width=250 .sidebar}
-----------------------------------------------------------------------

### I Want Those Values

```{r}
textInput(inputId = "input_Value", 
          label = "The value goes here", 
          value = "",
          placeholder = "Gimme that value")
```


Column {data-width=750}
-----------------------------------------------------------------------

### Chart B

```{r}
h3("Here is that value:")
renderText({
  if(check_VALUE_ONE(input$input_Value) == TRUE)
    input$input_Value
})
```

### Chart C

```{r}
h3("Is the value in the frame?:")
renderText({
   if(check_COMPLETE() == TRUE)
    "Success!"
 })
 ```

And the functions:

generate_VALUEFRAME <- function()
{
  FRAME <<- data.frame(VALUES = c("FIRSTVALUE"),
                   ENTRIES = c("NOTHING"),
                   COMPLETE = c(0),
                   IF_COMPLETE = c(2))
}

check_VALUE_ONE <- function(VALUE)
{
  letters <- str_count(VALUE)

 if(letters > 3)
  {
     FRAME[1,2] <- VALUE
     FRAME[1,3] <- FRAME[1,4]
     RETURN <- TRUE
  }
 else
    RETURN <- FALSE

  RETURN
 }

check_COMPLETE <- function()
{
  if(sum(FRAME$COMPLETE) == 2)
     RETURN <- TRUE
  else
     RETURN <- FALSE
}

As by the renderText-part it is clear that he went into check_VALUE_ONE, because the TRUE was needed to display the value, but the FRAME hasn't changed at all.

Any suggestions will be highly appreciated.

THX Daniel

Upvotes: 1

Views: 391

Answers (1)

NiklasvMoers
NiklasvMoers

Reputation: 329

The way shiny updates values is that it generates a directed "reactivity graph". If one of your reactive values (such as a value associated to sliderInput) changes, it "fires" along the directed edges of the reactivity graph, telling all reached vertices to update as well.

Since your data is supposed to be dynamic, it may be wise to make it reactive() e.g.

df <- reactive({
  # put your code returning a data.frame here
})

and then calling it using df() (instead of having it as a global variable). Inside of that reactive() call, you can use req(): This function can on one hand check if values are set and on the other hand, you can pass it a boolean expression (such as the return value of your check_COMPLETE(). If req() fails, your reactive object won't be updated.

Now, a problem I see with your code is that your function check_COMPLETE() doesn't return anything (to be precise, it returns NULL). I'm not quite sure what you are trying to do or why your code fails, but maybe you just need to return RETURN.

Upvotes: 1

Related Questions