कृपया, इस प्रयास करें:
दृष्टिकोण 1 (अनुशंसित)
library(shiny)
library(ggplot2)
# initialize global variable to record selected (clicked) rows
selected_points <- mtcars[0, ]
str(selected_points)
shinyApp(
ui = shinyUI(
plotOutput("plot", click = "clicked")
),
server = shinyServer(function(input, output) {
selected <- reactive({
# add clicked
selected_points <<- rbind(selected_points, nearPoints(mtcars, input$clicked))
# remove _all_ duplicates if any (toggle mode)
# http://stackoverflow.com/a/13763299/3817004
selected_points <<-
selected_points[!(duplicated(selected_points) |
duplicated(selected_points, fromLast = TRUE)), ]
str(selected_points)
return(selected_points)
})
output$plot <- renderPlot({
ggplot(mtcars, aes(x = mpg, y = wt)) +
geom_point() +
geom_point(data = selected(), colour = "red", size = 5)
})
})
)
आप एक बिंदु एक बार यह हाइलाइट किया गया है पर क्लिक करें। यदि आप इसे दूसरी बार क्लिक करते हैं तो हाइलाइट फिर से बंद हो जाता है (टॉगलिंग)।
कोड वास्तव में हाइलाइट किए गए (चयनित) अंक और एक प्रतिक्रियाशील अभिव्यक्ति selected()
स्टोर करने के लिए वैश्विक चर selected_points
का उपयोग करता है जो किसी भी बिंदु पर क्लिक होने पर वैश्विक चर अद्यतन करता है।
str(selected_points)
काम को देखने में मदद कर सकता है लेकिन हटाया जा सकता है।
दृष्टिकोण 2 (वैकल्पिक)
वहाँ एक अलग दृष्टिकोण है जो एक समारोह से वस्तु लौटने के बजाय सीधे observe()
बजाय reactive()
और संदर्भ वैश्विक चर selected_points
का उपयोग करता है:
library(shiny)
library(ggplot2)
selected_points <- mtcars[0, ]
str(selected_points)
shinyApp(
ui = shinyUI(
plotOutput("plot", click = "clicked")
),
server = shinyServer(function(input, output) {
observe({
# add clicked
selected_points <<- rbind(selected_points, nearPoints(mtcars, input$clicked))
# remove _all_ duplicates (toggle)
# http://stackoverflow.com/a/13763299/3817004
selected_points <<-
selected_points[!(duplicated(selected_points) |
duplicated(selected_points, fromLast = TRUE)), ]
str(selected_points)
})
output$plot <- renderPlot({
# next statement is required for reactivity
input$clicked
ggplot(mtcars, aes(x = mpg, y = wt)) +
geom_point() +
geom_point(data = selected_points, colour = "red", size = 5)
})
})
)
बेशक
, आप प्रतिक्रियाशील फ़ंक्शन selected()
पर कॉल करने के बजाय वैश्विक चर selected_points
सीधे ggplot
कॉल में उपयोग कर सकते हैं। हालांकि, आपको यह सुनिश्चित करना होगा कि renderPlot()
निष्पादित किया जाता है जब भी input$clicked
बदल जाता है। इसलिए, input$clicked
को डमी संदर्भ renderPlot()
के भीतर कोड में शामिल किया जाना है।
अब, प्रतिक्रियाशील फ़ंक्शन selected()
की आवश्यकता नहीं है और इसे observe()
अभिव्यक्ति द्वारा प्रतिस्थापित किया जा सकता है। reactive()
के विपरीत, observe()
कोई मान नहीं देता है। जब भी input$clicked
संशोधित होता है तो यह वैश्विक चर selected_points
अपडेट करता है।
दृष्टिकोण 3 (प्रतिक्रियाशील मान)
यह दृष्टिकोण एक वैश्विक चर बचा जाता है। इसके बजाय, यह प्रतिक्रियाशील प्रोग्रामिंग के लिए विशेष क्षमताओं के साथ सूची-जैसी वस्तु rv
बनाने के लिए reactiveValues
का उपयोग करता है (?reactiveValues
देखें)।
library(shiny)
library(ggplot2)
shinyApp(
ui = shinyUI(
plotOutput("plot", click = "clicked")
),
server = shinyServer(function(input, output) {
rv <- reactiveValues(selected_points = mtcars[0, ])
observe({
# add clicked
rv$selected_points <- rbind(isolate(rv$selected_points),
nearPoints(mtcars, input$clicked))
# remove _all_ duplicates (toggle)
# http://stackoverflow.com/a/13763299/3817004
rv$selected_points <- isolate(
rv$selected_points[!(duplicated(rv$selected_points) |
duplicated(rv$selected_points, fromLast = TRUE)), ])
str(rv$selected_points)
})
output$plot <- renderPlot({
ggplot(mtcars, aes(x = mpg, y = wt)) +
geom_point() +
geom_point(data = rv$selected_points, colour = "red", size = 5)
})
})
)
, कृपया ध्यान दें कि rv
को observer
हिस्सा संदर्भ में isolate()
में संक्षिप्त करने के लिए सुनिश्चित करें कि केवल input$clicked
में परिवर्तन observer
में कोड के निष्पादन को गति प्रदान करेगा की जरूरत है। अन्यथा, हम एक अंतहीन पाश प्राप्त करेंगे। renderPlot
का निष्पादन तब भी ट्रिगर होता है जब प्रतिक्रियाशील मान rv
बदल जाता है।
निष्कर्ष
व्यक्तिगत रूप से, मैं प्रतिक्रियाशील कार्य करता है जो निर्भरता (प्रतिक्रियात्मकता) अधिक स्पष्ट बनाने का उपयोग कर दृष्टिकोण 1 पसंद करते हैं। मुझे दृष्टिकोण 2 कम अंतर्ज्ञानी में क्लिक किए गए इनपुट इनपुट करने के लिए डमी कॉल मिलती है। दृष्टिकोण 3 को प्रतिक्रियाशीलता की पूरी तरह से समझने और सही स्थानों पर isolate()
का उपयोग करने की आवश्यकता है।
धन्यवाद कि यह सही है। सबसे पहले मुझे समझ में नहीं आया कि दूसरी 'geom_point' परत में डेटा स्रोत' चयनित() 'क्यों है, लेकिन अब मैं देख सकता हूं कि 'चयनित()' फ़ंक्शन 'select_points' ऑब्जेक्ट देता है। ब्याज से बाहर, क्या मेरे पास डेटा स्रोत के रूप में 'select_points' हो सकता है और ऑब्जेक्ट को फ़ंक्शन से वापस नहीं कर सकता? यदि हां, तो आप इसे दूसरे तरीके से क्यों करेंगे? – roman
ठीक है, यह प्रतिक्रियाशीलता के बारे में है या किसी विशेष डेटा को बदलते समय कोड का किस टुकड़ा निष्पादित किया जाएगा (प्रतिक्रियाशीलता)। हां, आप 'select_points' का उपयोग कर सकते हैं लेकिन आपको' इनपुट $ क्लिक 'पर डमी कॉल जोड़कर प्रतिक्रियाशीलता को लागू करना होगा (मेरे संपादित उत्तर के _Approach 2_ देखें)। मैं प्रतिक्रियाशील कार्यों का उपयोग करना पसंद करता हूं जो निर्भरताओं को अधिक स्पष्ट बनाते हैं। विस्तारित उत्तर के लिए – Uwe
धन्यवाद - बहुत उपयोगी। – roman