Das Problem ist, dass das Ausgabeobjekt auch alle Web-Display-Sachen erzeugt. Stattdessen müssen Sie die Daten separat für den Download abrufen. Sie könnten es mit einem zweiten Aufruf an brushedPoints
im Download-Code tun. Besser ist es jedoch, eine reactive()
Funktion zu verwenden, um es nur einmal zu tun, dann rufen Sie das überall an, wo Sie es brauchen. Hier ist, wie ich Ihren Code ändern würde, um diese Arbeit zu machen.
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)
(Beachten Sie, mit ggplot2
, die Sie nicht explizit festlegen müssen xvar
und yvar
in brushedPoints
So entfernte ich es hier erhöhen die Flexibilität der der Code.)
Ich bin nicht bewusst von "Lasso" Stil freie Zeichenfähigkeit in shiny
(obwohl, geben Sie es eine Woche - sie fügen ständig Spaß Werkzeuge). Sie können das Verhalten jedoch nachahmen, indem Sie dem Benutzer erlauben, mehrere Regionen auszuwählen und/oder auf einzelne Punkte zu klicken. Die Serverlogik wird viel unordentlicher, da Sie die Ergebnisse in einem reactiveValues
Objekt speichern müssen, um es wiederholt verwenden zu können. Ich habe etwas Ähnliches gemacht, um mir zu ermöglichen, Punkte auf einem Plot auszuwählen und sie auf anderen Plots zu markieren/zu entfernen. Das ist komplizierter als das, was Sie hier brauchen, aber das Folgende sollte funktionieren. Vielleicht möchten Sie andere Tasten/Logik hinzufügen (z. B. um die Auswahl "zurückzusetzen"), aber ich glaube, das sollte funktionieren. Ich habe eine Anzeige der Auswahl hinzugefügt, damit Sie verfolgen können, was ausgewählt wurde.
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)
Mark, das hat perfekt funktioniert! Die reaktive Funktion ist besonders hilfreich, danke, um mich darauf aufmerksam zu machen. Vielen Dank. – KrisF
Mark, es ist mir aufgefallen, dass die Option brushedPoints nur dem Benutzer erlaubt, Punkte innerhalb eines Rechtecks auszuwählen. Ist eine "Lasso" -Option möglich? Ich suchte herum, konnte aber in Plot.ly nur die "Lasso" -Option finden, die eine große Umschrift des obigen Skripts erfordern würde. – KrisF
Nicht direkt, das ist mir bewusst. Allerdings habe ich nur eine Änderung hinzugefügt, die zeigt, wie man mehrere Auswahlen macht - das kann am Ende dasselbe Verhalten ergeben. –