Shan
Shan

Reputation: 93

Lookup of value's location in a table of minimum and maximum ranges

I have a data frame in R for use in a shiny app. This data frame has a column for minimum values, and a column for maximum values. It's then got columns which are the return results.It looks like this:

Min Max Return ReturnifConditionTrue
71    80      40         30
81    90      45         35
91    100    50         40

Numbers will be received via user input. Once a number has been given, the range it falls in must be found. Once its corresponding range has been found, another amount from another column must be returned from the same row that range was in. If a certain condition is true, another column's result must be returned. For example if a user gives 85 as a value but the condition test is false, the function should return 45 as a result.

I haven't been able to find a solution. I've used an if in conjunction with a between and incremental for loop but this doesn't work (test for condition, then find where the between function returns true then match to column and return the value) , and I suspect that even if it did work, it'll be slow to implement since this function will be integrated into the server side of the shiny app. Is there a way of achieving this that works and may be more efficient? Thanks in advance.

Upvotes: 1

Views: 585

Answers (2)

Luiz Rodrigo
Luiz Rodrigo

Reputation: 936

What you're looking for is the function which(). It returns the positions where a certain condition is met. Then you can use an if statement to choose the column from which to pick up the value.

tb = data.frame(
  Min = c(71, 81, 91),
  Max = c(80, 90, 100),
  Return = c(40, 45, 50),
  ReturnifConditionTrue = c(30, 35, 40)
)

x = 75
condition = TRUE

pos = which(x >= tb$Min & x <= tb$Max)

if (condition) {
  val = tb$ReturnifConditionTrue[pos]
} else {
  val = tb$Return[pos]
}

Upvotes: 1

Florian
Florian

Reputation: 25395

You could do something like this:

df <- read.table(text="Min Max Return ReturnifConditionTrue
71    80      40         30
81    90      45         35
91    100    50         40",header=T)

library(shiny)

ui <- shinyUI(
  fluidPage(
numericInput("number","Number: ",min=71,max=100,value=85,step=1),
selectInput("condition","Condition:", choices=c("TRUE","FALSE")),
textOutput("text")
)
)

server <- function(input, output, session) {

  my_result <- reactive({
     our_row <- which(input$number>=df$Min & input$number<=df$Max)
     if(input$condition=="TRUE")
     {
       return(df[our_row,"ReturnifConditionTrue"])
     }
     else
     {
       return(df[our_row,"Return"])
     }

  })

  output$text <- renderText({my_result() })

}

shinyApp(ui,server)

Although you might consider changing your dataframe to:

df <- read.table(text="Min Max Return ReturnifConditionTrue
71    80      40         30
80    90      45         35
90    100    50         40",header=T)

and then changing the condition to

     our_row <- which(input$number>df$Min & input$number<=df$Max)

so it also works for continuous numbers.

I hope this helps!

Upvotes: 0

Related Questions