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.

Excluir puntos de datos haciendo clic en Plotly en una aplicación Shiny en R.

Quiero excluir ciertos puntos de datos que son seleccionados por el usuario al hacer clic, como en este ejemplo (pero usando plotly).
Intenté hacerlo con el código que muestro a continuación pero no funciona.

Lo que estoy intentando hacer es identificar la posición del punto de datos y luego, una vez que obtengo la posición, establecer la variable “delete” como “TRUE” si el “row_number()” está en el conjunto de puntos de datos seleccionados y luego filtrar si “delete” es “TRUE”.

No sé si esta es la forma más eficiente de hacerlo.

Agradecería cualquier ayuda o guía.

library(shiny)
library(plotly)
library(dplyr)

n   <- 20
x   <- 1:n 
y   <- cumsum(rnorm(n))
z   <- runif(n,10,200)
cat <- sample(letters[1:5],n,replace = TRUE)
delete <- FALSE

df<-data.frame(cat,x,y,z, delete)

ui <- fluidPage(

selectInput("var","var", c("y","z"), "y"),
  mainPanel(plotlyOutput("plot")),
  verbatimTextOutput("selection"),
  actionButton("delete","Delete", style = "display:inline-block;"),
  actionButton("reset","Reset", style = "display:inline-block;"),

)

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

myData <- reactive({df})

output$plot <- renderPlotly({

plot_ly(myData(), 
           x = ~x,
           y = ~get(input$var), 
           type = "scatter", 
           mode = "markers",
           text = ~cat,
           marker = list(size = 10),
           source = "A")

})

p1 <- reactive({

event_data("plotly_click", source = "A")

})

p2 <- reactiveValues(points = c())

observeEvent(p1(),{

p2$points <- c(p2$points,as.list(p1())$pointNumber)

})

observeEvent(input$reset,{

p2$points <- c()

})

output$selection <- renderPrint({ if(length(p2$points+1)<1){"Select data points to delete"}else{(p2$points+1)} })

observeEvent(input$delete,{

myData()  <- myData() %>%
       mutate(delete = ifelse(row_number() %in% c(p2$points+1),TRUE,delete)) %>%
       filter(!delete)
 })

}

shinyApp(ui, server)
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que hay un error en tu código, en p2$puntos+1 (debería ser p2$points+1) y falta una línea de código para actualizar el gráfico cuando se elimina un dato.

    Aquí tienes una versión modificada de tu código de servidor que debería funcionar:

    server <- function(input, output, session) {
    
      myData <- reactive({df})
    
      output$plot <- renderPlotly({
    
        plot_ly(myData(), 
                x = ~x,
                y = ~get(input$var), 
                type = "scatter", 
                mode = "markers",
                text = ~cat,
                marker = list(size = 10),
                source = "A") %>%
    
          event_register(event = "plotly_click", 
                         handler = "excludePoints",
                         handler_args = list(id = "A", modifyData = list(selectedpoints = NULL)))
      })
    
      p1 <- reactive({
        event_data("plotly_click", source = "A")
      })
    
      p2 <- reactiveValues(points = c())
    
      observeEvent(p1(), {
        p2$points <- c(p2$points, p1()$pointNumber)
      })
    
      observeEvent(input$reset,{
        p2$points <- c()
      })
    
      output$selection <- renderPrint({ 
        if(length(p2$points) < 1) {
          "Selecciona los puntos de datos para eliminar"
        } else {
          (p2$points+1)
        }
      })
    
      observeEvent(input$delete, {
        myData() <- myData() %>%
          mutate(delete = ifelse(row_number() %in% (p2$points+1), TRUE, FALSE)) %>%
          filter(!delete)
        p2$points <- c()
      })
    
    }
    

    Los cambios realizados en tu código incluyen:

    • Usar event_register() para registrar el evento “plotly_click” y especificar que los datos modificados deben restablecer los puntos seleccionados (modifyData = list(selectedpoints = NULL))
    • Corregir el error en p2$points+1
    • Agregar una línea de código para restablecer los puntos seleccionados después de eliminar datos (p2$puntos <- c()).

Comments are closed.