0

I am making a Shiny App where I generate a file with the DNA sequences of the organism that the user indicates. This file is created instantly but is not filled until after a few seconds and while R goes to the next command. The App stops because the next command needs this file and finds it empty (because it is still being generated). What command can I put so that R waits until the file is full? Or just wait a few seconds.

The code is:

# LIBRARIES
library(shiny)
library(dplyr)
library(pr2database)
library(Biostrings) # To save fasta files
library(base)
library(treeio) # tree manipulation
library(ggtree)
library(readr)

# Functions
treeplot <- function(tree){
  ggtree(tree) + 
    xlim(0, 0.08) +
    geom_tiplab(size=4, color='#a52a2a') + 
    geom_text2(aes(subset=!isTip, label=node), # labels all the nodes in the tree
               size = 3.5,
               color = "#87a96b",
               hjust = 1.3, 
               vjust = 1.5) 
}

plotrename <- function(tree){
  ggtree(tree) + 
    geom_text2(aes(subset=!isTip, label=node), # labels all the nodes in the tree
               size = 3.5,
               color = "#87a96b",
               hjust = 1.3, 
               vjust = 1.5) 
}

ui <- fluidPage(
  
  titlePanel("Shiny App"),
  
  # Sidebar layout with input and output definitions
  sidebarLayout(
    
    # Sidebar panel for inputs
    sidebarPanel(
      
      # Input: Selector for choosing dataset
      selectInput(inputId = "tax",
                  label = "Choose taxonomic group:",
                  choices = c("Domain", "Kingdom", "Phylum", "Class", "Order", "Family", "Genus", "Species"),
                  selected = "Order"),
      
      # Input: Text for providing a caption
      textInput(inputId = "clade",
                label = "Group name:",
                value = "Suessiales"),
   
      checkboxInput(inputId = "root",
                    label = strong("Reroot")),
      
      numericInput(inputId = "val_root",
                   label = "Branch number:",
                   value = 87),
      
      checkboxInput(inputId = "rot",
                    label = strong("Rotate")),
      
      numericInput(inputId = "val_rot",
                   label = "Branch number:",
                   value = 87),
      
      checkboxInput(inputId = "flip",
                    label = strong("Flip")),
      
      numericInput(inputId = "val_f1",
                   label = "Node 1 number:",
                   value = 87),
      
      numericInput(inputId = "val_f2",
                   label = "Node 2 number:",
                   value = 72),
      
      checkboxInput(inputId = "rename",
                    label = strong("Rename branches"))

    ),

# Main panel for displaying outputs ----
    mainPanel(
      plotOutput("tree"),

      plotOutput("root"),

      plotOutput("rotate"),

      plotOutput("flip"), 
      
      plotOutput("rename")      
      
    )
  )
)

# Define server logic to summarize and view selected dataset ----
server <- function(input, output) {
  
  # Input SelectBox and TextInput
  mydf <- reactive({
    group <- switch(input$tax,
                    "Domain" = pr2 %>% dplyr::filter(domain == input$clade) %>% dplyr::select(genbank_accession, sequence_length, sequence),
                    "Kingdom" = pr2 %>% dplyr::filter(kingdom == input$clade) %>% dplyr::select(genbank_accession, sequence_length, sequence),
                    "Phylum" = pr2 %>% dplyr::filter(phylum == input$clade) %>% dplyr::select(genbank_accession, sequence_length, sequence),
                    "Class" = pr2 %>% dplyr::filter(class == input$clade) %>% dplyr::select(genbank_accession, sequence_length, sequence),
                    "Order" = pr2 %>% dplyr::filter(order == input$clade) %>% dplyr::select(genbank_accession, sequence_length, sequence),
                    "Family" = pr2 %>% dplyr::filter(family == input$clade) %>% dplyr::select(genbank_accession, sequence_length, sequence),
                    "Genus" = pr2 %>% dplyr::filter(genus == input$clade) %>% dplyr::select(genbank_accession, sequence_length, sequence),
                    "Species" = pr2 %>% dplyr::filter(species == input$clade) %>% dplyr::select(genbank_accession, sequence_length, sequence))
    
    return(group)
  })
  
  # Function: convert p
  seq_clade <- function(x){
    seq_clade <- Biostrings::DNAStringSet(x$sequence)
    names(seq_clade) <- paste(x$genbank_accession, sep="|")
    Biostrings::writeXStringSet(seq_clade, "~/pr2_CLADE.fa", width = 80)
  }
  
  
  output$pr2 <- renderDataTable({
    seq_clade(mydf())
  })
  
  # while (!file.exists("pr2_CLADE.fa")) {
  #   Sys.sleep(1)
  # }
 
   # Vsearch
   system("vsearch --sortbylength pr2_CLADE.fa --output CLADE_sort.fa --minseqlength 500 -notrunclabels")

}

# Create Shiny app ----
shinyApp(ui, server)

I have tried this code but inside Shiny it makes the app stop.

while (!file.exists("pr2_CLADE.fa")) {
  Sys.sleep(1)
}

I have algo tried Sys.time(), Sys.sleep() and evalWithtimeout().

  • You can suspend Shiny messaging using Javascript. There is a post about it. [Suspending event scheduling in Shiny](https://stackoverflow.com/questions/71406486/suspending-event-scheduling-in-shiny). Hope it helps. – Jan Jul 19 '22 at 19:42

1 Answers1

1

I'm not familiar with these packages and I'm not sure to understand what you want to do but maybe:

do_seq_clade <- function(x){
  seq_clade <- Biostrings::DNAStringSet(x$sequence)
  names(seq_clade) <- paste(x$genbank_accession, sep="|")
  seq_clade
}

SeqClade <- reactiveVal()

observeEvent(mydf(), {
  seq_clade <- do_seq_clade(mydf())
  SeqClade(seq_clade)
  Biostrings::writeXStringSet(seq_clade, "~/pr2_CLADE.fa", width = 80)
  # Vsearch
  system("vsearch --sortbylength pr2_CLADE.fa --output CLADE_sort.fa --minseqlength 500 -notrunclabels")
})

output$pr2 <- renderDataTable({
  seq_clade(mydf())
})
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225