How to run an R function getpoints() from IPDfromKM package in an R shiny app which in R pops up a plot that utilizes clicks to capture coordinates?

25 views Asked by At

I am trying to convert some R code I've written into an R shiny app so others can use it more readily. The code utilizes a package called IPDfromKM. The main function of issue is getpoints(), which in R will generate a plot and the user will need to click the max X and max Y coordinates, followed by clicking through the entire KM curve, which extracts the coordinates into a data frame. However, I cannot get this to work in my R shiny app.

There is a link to the working R shiny app from the creator

This is the getpoints() code:

getpoints <- function(f,x1,x2,y1,y2){

  ## if bitmap
  if (typeof(f)=="character")
      { lfname <- tolower(f)
       if ((strsplit(lfname,".jpeg")[[1]]==lfname) && (strsplit(lfname,".tiff")[[1]]==lfname) &&
            (strsplit(lfname,".bmp")[[1]]==lfname) && (strsplit(lfname,".png")[[1]]==lfname) &&
           (strsplit(lfname,".jpg")[[1]]==lfname))
         {stop ("This function can only process bitmap images in JPEG, PNG,BMP, or TIFF formate.")}
       img <- readbitmap::read.bitmap(f)
      } else if (typeof(f)=="double")
      {
        img <- f
      } else {
        stop ("Please double check the format of the image file.")
      }
  ## function to read the bitmap and points on x-axis and y-axis
  axispoints <- function(img){
    op <- par(mar = c(0, 0, 0, 0))
    on.exit(par(op))
    plot.new()
    rasterImage(img, 0, 0, 1, 1)
    message("You need to define the points on the x and y axis according to your input x1,x2,y1,y2. \n")
    message("Click in the order of left x-axis point (x1), right x-axis point(x2),
      lower y-axis point(y1), and upper y-axis point(y2). \n")
    x1 <- as.data.frame(locator(n = 1,type = 'p',pch = 4,col = 'blue',lwd = 2))
    x2 <- as.data.frame(locator(n = 1,type = 'p',pch = 4,col = 'blue',lwd = 2))
    y1 <- as.data.frame(locator(n = 1,type = 'p',pch = 3,col = 'red',lwd = 2))
    y2 <- as.data.frame(locator(n = 1,type = 'p',pch = 3,col = 'red',lwd = 2))
    ap <- rbind(x1,x2,y1,y2)
    return(ap)
  }

  ## function to calibrate the points to the appropriate coordinates
  calibrate <-  function(ap,data,x1,x2,y1,y2){
    x  <- ap$x[c(1,2)]
    y  <- ap$y[c(3,4)]
    cx <- lm(formula = c(x1,x2) ~ c(x))$coeff
    cy <- lm(formula = c(y1,y2) ~ c(y))$coeff
    data$x <- data$x*cx[2]+cx[1]
    data$y <- data$y*cy[2]+cy[1]
    return(as.data.frame(data))
   }

  ## take the points
  ap <- axispoints(img)
  message("Mouse click on the K-M curve to take the points of interest. The points will only be labled when you finish all the clicks.")
  takepoints <- locator(n=512,type='p',pch=1,col='orange4',lwd=1.2,cex=1.2)
  df <- calibrate(ap,takepoints,x1,x2,y1,y2)
  par()
  return(df)
}

I'm a bit at a loss in how to execute this in my main panel. I've tried using plotOutput(), imageOutput(), and calling variations of the below functions, but nothing pops up or seems to work like it does in R studio. I feel like the issue is that the 'getpoints()' function executes 3 things :

  1. Displaying an image from an uploaded file.

  2. Allow user to click and store multiple points.

  3. Return a data frame.

Will I need to split out the components of the function into individual steps?

createPoints<-reactive({
    
    #Read File
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    req(file)
    validate(need(ext == "png", "Please upload a .png file"))
    
    ##should run the function that generates a plot for clicking coordinates and stores them in a data frame
    points<-getpoints(file,x1=0, x2=input$Xmax,y1=0, y2=100)
  
    return(points)
    
  })
output$getPointsPlot<-renderPlot(
    
    createPoints()
    
  )
0

There are 0 answers