How to repeatedly call a function in R shiny

In ui.R function, I upload a CSV file that has 10 rows. In server.R function, I want to apply my function (called myFun) to the input data and another data (read from "data2.csv" file which was created in advance using complicated R code) repeatedly. I need help in: (1) how to read the "data2.csv" file in server.R? (2) how to call function myFun repeatedly without writing the same function 10 times? I heard that global.R file could do the trick. But I don't know how to do it. Could someone help?
Here is the example:

library(shiny)
ui <- shinyUI(fluidPage(
  titlePanel("upload your input data"),
  sidebarLayout(
    sidebarPanel(
      shinyFeedback::useShinyFeedback(),      
      fileInput("file1","Upload CSV file", accept = c(".csv"), multiple = T), # fileinput() function is used to get the file upload control option
    ),
    mainPanel(
      uiOutput("tb"),
      verbatimTextOutput(outputId = "warning1"),
      textOutput("warning2")
    )
  )
))


server <- shinyServer(function(input,output) {
  output$filedf1 <- renderTable({
     input$file1 # the file input data frame object that contains the file attributes
  })

  data.chg <- reactive({
    data.input<- read.csv(input$file1$datapath)
    data.global<- read.csv("data2.csv")
    data.output<- data.input
   for (i in 1:nrow(data.input)){ 
     data.output[i,1]<- myFun(data.input[i,1], data.output[i,1]) 
   }
   list(data.input= data.input, data.output=data.output)
  })
  output$data.origin <- renderDataTable({
    req(input$file1)
    dataset<- data.chg()$data.input
    dataset
  })
  output$results <- renderDataTable({
    req(input$file1)
    dataset<- data.chg()$data.output
    dataset
  })
output$tb <- renderUI({
    req(input$file1) 
      tabsetPanel(
        tabPanel("input data", dataTableOutput("data.origin")),
        tabPanel("Output", dataTableOutput("results")) 
      )
  })
})
# Run the application 
shinyApp(ui = ui, server = server)

Can you be more clear on where your code is breaking down? Is your code not doing what you want?

The following code

data.global<- read.csv("data2.csv")

gives error. This file "data2.csv" is created by some other R script in advance, and I want it to be fixed (no need user input). Another help I need is from the following code inside for loop:

data.output[i,1]<- myFun(data.input[i,1], data.output[i,1]) 

where myFun function is called 10 times. The function myFun is very big. Should I write reactive expression for myFun each time this function is called? I searched website, the message I got is that using global.R file can make myFun accessible without using reactive expression in server.R file. If I create a global.R file that includes definition of myFun function and the code data.global<- read.csv("data2.csv") , would this work in R shiny web server?

I think we still need to get a little more specific:

What error does data.global <- read.csv('data2.csv') give you?

And why do you need to call myFun ten times? Are you going over the indices of data.input and data.output? Or does myFun have an element of randomness to it where you will not get the same result every time? Or do you just need a 10 element vector with the results of one call to myFun?

The error message when I run it in my local computer is "cannot open the connection". When I run it in web server, it is "Not found". The reason I need to call myFun(x, y) multiple times is because I use 10 different combinations of x and y values (computed from many lines of code) and want to get a value from myFun(x, y). I used a for loop in my toy example. The actually code looks like this (very long):

(code to compute the first pair of x and y)
data.output[1,1]<- myFun(x, y)
(new code, not the same as before, to compute the second pair of x and y)
data.output[2,1]<- myFun(x, y)
...
(new code, not the same as before, to compute the 10th pair of x and y)
data.output[10,1]<- myFun(x, y)

The myFun code itself is very long too. I try to make server.R file shorter and easy to read. Thanks

myFun(x, y) does not have an element of randomness. It just contains many long formulas. It gives the same value for the same x and y pair.

1 Like

if myFun is vectorised you can use it directly without an explicit loop at all.

(data_input <- data.frame(
  x = 1:5,
  y = 5:1
))

my_vectorised_fun <- function(x, y) {
  x^2 + 2 * y + 1
}

data_output <- data_input
data_output$results <- my_vectorised_fun(
  data_input$x,
  data_input$y
)

data_output

You can use one of the many apply functions depending on your use case.

Another alternative is to use the for construct to get things done.

Given my understanding of your requirements:

for(x in 1:10) {
  for (y in 1:10) {
    data.output[x,y] <- myFun(x,y)
  }
} 

I think you need to restructure your code, no code should be that long

This is a great idea! Would it possible to extend it if my x and y are matrices? Sorry for my naive questions since I am new to R shiny.

(data_input <- tibble(
  x = list(matrix(1:4,nrow=2),matrix(2:5,nrow=2)),
  y = list(matrix(2:5,nrow=2),matrix(3:6,nrow=2))
))

my_vectorised_fun <- Vectorize(function(x, y) {
  list(x^2 + 2 * y + 1)
})

data_output <- data_input
data_output$results <- my_vectorised_fun(
  data_input$x,
  data_input$y
)

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.