2016-08-26 38 views
6

Próbuję napisać małą aplikację, która pozwoli użytkownikowi zrobić wykres rozrzutu, wybrać podzbiór punktów na wykresie, a następnie wypisać tabelę w formacie .csv z tylko wybranymi punktami. Zorientowałem się, jak uruchomić stronę i jak wybierać punkty za pomocą szczotkowanych punktów. Zostanie wyświetlona tabela z wybranymi punktami, ale po naciśnięciu przycisku Pobierz wystąpi błąd "Odczytywanie obiektów z obiektu błyszczącego przebiegu nie jest dozwolone". pojawia się. Czy nie mogę pobrać tabeli, którą mogę wizualnie zobaczyć na ekranie jako .csv? Jeśli tak, czy istnieje obejście?Czytanie obiektów z błyszczącego obiektu wyjściowego jest zabronione?

Odtworzyłem problem za pomocą poniższego zestawu danych tęczówki. Jakąkolwiek pomoc w ustaleniu, dlaczego nie mogę pobrać tabeli wyświetlanych wierszy, byłaby bardzo doceniana.

data(iris) 

ui <- basicPage(
    plotOutput("plot1", brush = "plot_brush"), 
    verbatimTextOutput("info"),mainPanel(downloadButton('downloadData', 'Download')) 
) 


server <- function(input, output) { 
    output$plot1 <- renderPlot({ 
ggplot(iris,aes(x=Sepal.Width,y=Sepal.Length)) + 
    geom_point(aes(color=factor(Species))) + 
    theme_bw() 
    }) 

    output$info <- renderPrint({ 
brushedPoints(iris, input$plot_brush, xvar = "Sepal.Width", yvar = "Sepal.Length") 
    }) 

    output$downloadData <- downloadHandler(
     filename = function() { 
     paste('SelectedRows', '.csv', sep='') }, 
     content = function(file) { 
     write.csv(output$info, file) 
     } 
) 

} 


shinyApp(ui, server) 

Odpowiedz

10

Problem polega na tym, że obiekt wyjściowy generuje również wszystkie elementy wyświetlania w Internecie. Zamiast tego musisz pobrać dane osobno do pobrania. Możesz to zrobić, wykonując drugie połączenie z brushedPoints w kodzie pobierania. Lepiej jednak użyć funkcji reactive(), aby zrobić to tylko raz, a następnie wywołać to wszędzie, gdy jest to potrzebne. Oto w jaki sposób zmodyfikować kod, aby tę pracę.

data(iris) 

ui <- basicPage(
    plotOutput("plot1", brush = "plot_brush"), 
    verbatimTextOutput("info"),mainPanel(downloadButton('downloadData', 'Download')) 
) 


server <- function(input, output) { 
    output$plot1 <- renderPlot({ 
    ggplot(iris,aes(x=Sepal.Width,y=Sepal.Length)) + geom_point(aes(color=factor(Species))) + theme_bw() 
    }) 


    selectedData <- reactive({ 
    brushedPoints(iris, input$plot_brush) 
    }) 

    output$info <- renderPrint({ 
    selectedData() 
    }) 

    output$downloadData <- downloadHandler(
    filename = function() { 
     paste('SelectedRows', '.csv', sep='') }, 
    content = function(file) { 
     write.csv(selectedData(), file) 
    } 
) 

} 


shinyApp(ui, server) 

(banknotu z ggplot2, nie trzeba jawnie ustawić xvar i yvar w brushedPoints Więc usunąłem go tutaj, aby zwiększyć elastyczność kod.)

Nie jestem świadomy żadnej umiejętności "rysowania" w stylu lasso w shiny (choć, dajcie mu tydzień - ciągle dodają fajne narzędzia). Można jednak naśladować zachowanie, umożliwiając użytkownikowi wybranie wielu regionów i/lub kliknięcie poszczególnych punktów. Logika serwera staje się coraz bardziej niepotrzebna, ponieważ trzeba przechowywać wyniki w obiekcie reactiveValues, aby móc go używać wielokrotnie. Zrobiłem coś podobnego, aby pozwolić mi wybrać punkty na jednej działce i zaznaczyć/usunąć je na innych działkach. To jest bardziej skomplikowane niż to, czego potrzebujesz tutaj, ale poniższe powinny działać. Możesz dodać inne przyciski/logikę (np., Aby "zresetować" selekcje), ale uważam, że powinno to zadziałać. Dodałem wyświetlanie zaznaczenia do wykresu, aby umożliwić śledzenie tego, co zostało wybrane.

data(iris) 

ui <- basicPage(
    plotOutput("plot1", brush = "plot_brush", click = "plot_click") 
    , actionButton("toggle", "Toggle Seletion") 
    , verbatimTextOutput("info") 
    , mainPanel(downloadButton('downloadData', 'Download')) 
) 


server <- function(input, output) { 
    output$plot1 <- renderPlot({ 

    ggplot(withSelected() 
      , aes(x=Sepal.Width 
       , y=Sepal.Length 
       , color=factor(Species) 
       , shape = Selected)) + 
     geom_point() + 
     scale_shape_manual(
     values = c("FALSE" = 19 
        , "TRUE" = 4) 
     , labels = c("No", "Yes") 
     , name = "Is Selected?" 
    ) + 
     theme_bw() 
    }) 

    # Make a reactive value -- you can set these within other functions 
    vals <- reactiveValues(
    isClicked = rep(FALSE, nrow(iris)) 
) 


    # Add a column to the data to ease plotting 
    # This is really only necessary if you want to show the selected points on the plot 
    withSelected <- reactive({ 
    data.frame(iris 
       , Selected = vals$isClicked) 
    }) 



    # Watch for clicks 
    observeEvent(input$plot_click, { 

    res <- nearPoints(withSelected() 
         , input$plot_click 
         , allRows = TRUE) 

    vals$isClicked <- 
     xor(vals$isClicked 
      , res$selected_) 
    }) 


    # Watch for toggle button clicks 
    observeEvent(input$toggle, { 
    res <- brushedPoints(withSelected() 
         , input$plot_brush 
         , allRows = TRUE) 

    vals$isClicked <- 
     xor(vals$isClicked 
      , res$selected_) 
    }) 

    # pull the data selection here 
    selectedData <- reactive({ 
    iris[vals$isClicked, ] 
    }) 

    output$info <- renderPrint({ 
    selectedData() 
    }) 

    output$downloadData <- downloadHandler(
    filename = function() { 
     paste('SelectedRows', '.csv', sep='') }, 
    content = function(file) { 
     write.csv(selectedData(), file) 
    } 
) 

} 


shinyApp(ui, server) 
+0

Znak, działało idealnie! Funkcja reaktywna jest szczególnie pomocna, dzięki za zwrócenie jej uwagi. Dzięki wielkie. – KrisF

+0

Mark, przyszło mi do głowy, że opcja brushedPoints pozwala użytkownikowi wybrać punkty w prostokącie. Czy jest dostępna opcja "lasso"? Szukałem, ale nie mogłem znaleźć nic poza opcją "lasso" w Plot.ly, która wymagałaby ogromnego przepisania powyższego skryptu. – KrisF

+0

Nie bezpośrednio, o czym wiem. Dodałem jednak edycję, która pokazuje, jak dokonać wielu wyborów - może to w końcu dać takie samo zachowanie. –