es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo mostrar múltiples archivos .xpt en R Shiny y filtrarlos en función de sus columnas?

Cuando intento cargar varios archivos .xpt para mostrar las tablas en el panel principal de la aplicación R shiny, me da el siguiente problema.

También estoy buscando la opción de filtrado. Me gustaría filtrar por columnas mientras cargo varios archivos para que se muestren las filas adecuadas en el panel principal de cada marco de datos / tabla.

Error:
Advertencia: Error en Este tipo de entrada no se maneja

¿Alguien puede ayudarme con la solución?

Código:

library(shiny)
library(haven)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("file1", "Choose CSV File", multiple = TRUE,
                accept = c(
                  "text/csv",
                  "text/comma-separated-values,text/plain",
                  ".csv", ".xpt")
      ),
      tags$hr(),
      checkboxInput("header", "Header", TRUE)
    ),
    mainPanel(
      tableOutput("contents")
    )
  )
)

server <- function(input, output) {
  # output$contents <- renderTable({
  #   # input$file1 will be NULL initially. After the user selects
  #   # and uploads a file, it will be a data frame with 'name',
  #   # 'size', 'type', and 'datapath' columns. The 'datapath'
  #   # column will contain the local filenames where the data can
  #   # be found.
  #   inFile <- input$file1
  #
  #   if (is.null(inFile))
  #     return(NULL)
  #
  #   read.csv(inFile$datapath, header = input$header)
  # })

  output$contents <- renderTable({
    # input$file1 will be NULL initially. After the user selects
    # and uploads a file, it will be a data frame with 'name',
    # 'size', 'type', and 'datapath' columns. The 'datapath'
    # column will contain the local filenames where the data can
    # be found.
    inFile <- input$file1

if (is.null(inFile))
  return(NULL)

read_xpt(inFile$datapath) 

})

}

shinyApp(ui, server)

Xpt1:

STUDYID   DOMAIN    CR_VALUE
1           CR        1.5
2           CR        1.5
3           CR        1.5

Xpt2:

STUDYID   DOMAIN    CM_VALUE
1           CM        1.5
2           CM        1.8
3           CR        1.9

Después de filtrar con el valor 1.9, este es el resultado esperado.

3           CR        1.9
Tags:  ,

Answer

  1. Avatar for davy.ai

    El problema parece relacionado con el hecho de que la función fileInput acepta varios tipos de archivos, incluyendo archivos .csv y .xpt, pero el código en la función del servidor solo está configurado para leer archivos .xpt. Esto causa un problema al intentar leer un archivo .csv y también puede estar provocando el problema de filtrado.

    Para abordar este problema, podrías modificar la función del servidor para verificar la extensión de archivo de cada archivo cargado y leerlo en consecuencia. Aquí tienes un ejemplo de cómo se puede hacer esto:

    “`{r}
    server <- function(input, output) {
    output$contents <- renderTable({
    # input$file1 será NULL inicialmente. Después de que el usuario seleccione
    # y cargue un archivo, será un data frame con columnas ‘name’,
    # ‘size’, ‘type’ y ‘datapath’. La columna ‘datapath’
    # contendrá los nombres de archivo locales donde se encuentra los datos.
    inFiles <- input$file1

    if (is.null(inFiles))
      return(NULL)
    
    # crear una lista vacía para almacenar los data frames
    dfs <- list()
    
    # recorrer cada archivo cargado y leerlo según el tipo de archivo
    for (i in seq_along(inFiles$name)) {
      if (tools::file_ext(inFiles$name[i]) == "xpt") {
        dfs[[i]] <- read_xpt(inFiles$datapath[i])
      } else if (tools::file_ext(inFiles$name[i]) %in% c("csv", "txt")) {
        dfs[[i]] <- read.csv(inFiles$datapath[i], header = input$header)
      } else {
        # manejar otros tipos de archivo según sea necesario
        # por ejemplo, emitir un aviso o omitir el archivo
      }
    }
    
    # combinar los data frames en un solo data frame
    df <- do.call(rbind, dfs)
    
    # filtrar el data frame según la entrada del usuario
    if (!is.null(input$filter)) {
      df <- df[df[,input$column] == input$filter,]
    }
    
    # devolver el data frame filtrado
    df
    

    })

    # configurar la interfaz de filtrado
    output$filter <- renderUI({
    if (!is.null(input$file1)) {
    selectInput(“filter”, “Filtrar por:”,
    choices = c(“”, unique(names(input$file1)))),
    selectInput(“column”, “Columna:”,
    choices = c(“”, names(input$file1)))
    }
    })
    }


    Con este código actualizado, la función del servidor recorre cada archivo cargado y lo lee según el tipo de archivo. Luego combina los data frames en un solo data frame, que se puede filtrar según la entrada del usuario utilizando los widgets selectInput. Ten en cuenta que las opciones de filtro y columna se han agregado a la interfaz de usuario utilizando renderUI y selectInput, y los valores de entrada correspondientes se utilizan en la función del servidor para filtrar el data frame. Para filtrar el panel principal de cada data frame/tabla según la opción de filtrado del usuario, podrías modificar el código anterior para incluir un bucle adicional que aplique el filtrado a cada data frame por separado. Aquí tienes un ejemplo actualizado: ```{r} server <- function(input, output) { output$contents <- renderTable({ # input$file1 será NULL inicialmente. Después de que el usuario seleccione # y cargue un archivo, será un data frame con columnas 'name', # 'size', 'type' y 'datapath'. La columna 'datapath' # contendrá los nombres de archivo locales donde se encuentra los datos. inFiles <- input$file1 if (is.null(inFiles)) return(NULL) # crear una lista vacía para almacenar los data frames dfs <- list() # recorrer cada archivo cargado y leerlo según el tipo de archivo for (i in seq_along(inFiles$name)) { if (tools::file_ext(inFiles$name[i]) == "xpt") { dfs[[i]] <- read_xpt(inFiles$datapath[i]) } else if (tools::file_ext(inFiles$name[i]) %in% c("csv", "txt")) { dfs[[i]] <- read.csv(inFiles$datapath[i], header = input$header) } else { # manejar otros tipos de archivo según sea necesario # por ejemplo, emitir un aviso o omitir el archivo } } # recorrer cada data frame y filtrarlo según la entrada del usuario for (i in seq_along(dfs)) { if (!is.null(input$column) && input$column %in% colnames(dfs[[i]])) { dfs[[i]] <- dfs[[i]][dfs[[i]][,input$column] == input$filter,] } } # combinar los data frames en un solo data frame df <- do.call(rbind, dfs) # devolver el data frame filtrado df }) # configurar la interfaz de filtrado output$filter <- renderUI({ if (!is.null(input$file1)) { selectInput("filter", "Filtrar por:", choices = c("", unique(names(input$file1)))), selectInput("column", "Columna:", choices = c("", names(input$file1))) } }) }

    Con este código actualizado, la función del servidor incluye un bucle adicional que aplica el filtrado a cada data frame por separado. Cada data frame se filtra según la entrada del usuario para las opciones de columna y filtro, y los resultados se combinan en un solo data frame para mostrar en el panel principal.

Comments are closed.