Ошибка при запуске приложения R Shiny: операция запрещена без активного реактивного контекста - PullRequest
1 голос
/ 05 апреля 2019

Я использую Shiny и R для интерактивной визуализации моих данных. Я хотел бы нарисовать интерактивную диаграмму рассеяния Petal.Width и Petal.Length в наборе данных Iris и кластеризовать точки на основе k кластеров (пользовательский ввод) и p, процентного содержания строк данных, выделенных для обучающего набора данных (пользовательский ввод). Я добавил функцию наведения на диаграмму рассеяния, чтобы при нажатии на каждую точку был продемонстрирован весь набор данных для этой точки.

Вывод должен выглядеть так: enter image description here

# Loading Libraries
library(shiny)
library(caret)
library(ggplot2)
data(iris)


ui <- pageWithSidebar(
  headerPanel("Clustering iris Data"),

  sidebarPanel(
    sliderInput("k", "Number of clusters:",
                min = 1, max = 5,  value = 3),

    sliderInput("prob", "Training percentage:",
                min=0.5, max=0.9, value = 0.7)),

  mainPanel(
  # img(src='iris_types.jpg', align = "center", height="50%", width="50%"),

  plotOutput("plot1", click = "plot_click"),
  verbatimTextOutput("info")
  )
)


server <- function(input, output) {

  inTrain  <- createDataPartition(y=iris$Species, 
                                  p=input$prob, 
                                  list=FALSE)
  training <- iris[ inTrain,]
  testing  <- iris[-inTrain,]

  kMeans1 <- kmeans(subset(training,
                           select=-c(Species)),
                           centers=input$k)

  training$clusters <- as.factor(kMeans1$cluster)

  output$plot1 <- renderPlot({
    qplot(Petal.Width,
          Petal.Length,

          colour = clusters,
          data   = training,

          xlab="Petal Width",
          ylab="Petal Length")
  })

  output$info <- renderPrint({
    # With ggplot2, no need to tell it what the x and y variables are.
    # threshold: set max distance, in pixels
    # maxpoints: maximum number of rows to return
    # addDist: add column with distance, in pixels
    nearPoints(iris, input$plot_click, threshold = 10, maxpoints = 1,
               addDist = FALSE)
  })
}

shinyApp(ui, server)

Когда я запускаю приложение в R Studio, я получаю следующую ошибку:

Error in .getReactiveEnvironment()$currentContext() : 
  Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)

1 Ответ

1 голос
/ 05 апреля 2019

Как уже упоминалось @Clemsang, вы используете значения реактивов вне функции oberserver/render*.

То, что вы хотите сделать, - это создать reactive среду, в которой вы используете свои входные данные. То есть то, что пересчитывается при изменении входных данных. Таким образом, вам нужно обернуть ваш тренировочный расчет в reactive, и когда вы хотите использовать его в своей функции рендеринга, вы «вызываете» его, добавляя (). Мне нравится называть свои реактивы глаголом, чтобы подчеркнуть тот факт, что я действительно что-то делаю, когда эти функции вызываются, отсюда и название get_training_data:

server <- function(input, output) {

  get_training_data <- reactive({ ## now your inputs are in a reactive environment
     inTrain  <- createDataPartition(y=iris$Species, 
                                     p=input$prob, 
                                     list=FALSE)
     training <- iris[ inTrain,]
     testing  <- iris[-inTrain,]

     kMeans1 <- kmeans(subset(training,
                              select=-c(Species)),
                       centers=input$k)

     training$clusters <- as.factor(kMeans1$cluster)
     training
  })

  output$plot1 <- renderPlot({
    qplot(Petal.Width,
          Petal.Length,

          colour = clusters,
          data   = get_training_data(),

          xlab="Petal Width",
          ylab="Petal Length")
  })

  output$info <- renderPrint({
    # With ggplot2, no need to tell it what the x and y variables are.
    # threshold: set max distance, in pixels
    # maxpoints: maximum number of rows to return
    # addDist: add column with distance, in pixels
    nearPoints(iris, input$plot_click, threshold = 10, maxpoints = 1,
               addDist = FALSE)
  })
}
...