2015-08-13 2 views
2

Я пытаюсь разработать блестящее приложение, в котором пользователь может загружать файлы csv, которые впоследствии анализируются с помощью моего R-скрипта. Поэтому я хотел бы отображать динамическое количество графиков на основе количества обрабатываемых файлов (по одному графику для каждого файла).Динамически создавать графики на основе количества загружаемых файлов в Shiny

Я нашел this вопрос чрезвычайно полезный, но я не знаю максимальное количество заговоров заранее. Вот то, что я пробовал:

shinyServer(function(input, output) { 

    # Insert the right number of plot output objects into the web page 
    output$densityPlots <- renderUI({ 
    plot_output_list <- lapply(1:length(input$file1$datapath), function(i) { 
     plotname <- paste("densityPlot", i, sep="") 
     plotOutput(plotname) 
    }) 

    # Convert the list to a tagList - this is necessary for the list of items 
    # to display properly. 
    do.call(tagList, plot_output_list) 
    }) 

    # Call renderPlot for each one. Plots are only actually generated when they 
    # are visible on the web page. 
    for (i in 1:length(input$file1$datapath)) { 
    # Need local so that each item gets its own number. Without it, the value 
    # of i in the renderPlot() will be the same across all instances, because 
    # of when the expression is evaluated. 
    local({ 
     my_i <- i 
     plotname <- paste("densityPlot", my_i, sep="") 
     output[[plotname]] <- renderPlot({ 
     plot(1) 
     }) 
    }) 
    } 
} 

Однако, это дает мне эту ошибку:

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.) 

Я пытался поставить для цикла внутри функции вывода, но не участки не создаются вообще.

ответ

2

Я мог бы заставить его работать. Надо использовать реактивный проводник для создания участков, как описан here

shinyServer(function(input, output) { 

    createPlots <- reactive ({ 
    numberOfFiles <- length(input$files$datapath) 
    for (i in 1:numberOfFiles) { 
     local({ 
     my_i <- i 
     plotname <- paste("plot", my_i, sep="") 
     File <- read.csv(input$files$datapath[my_i]) 
     output[[plotname]] <- renderPlot({ 
      result <- runDensity(File, f) 
      plot(result$data, main=id, pch=19,cex=0.2, col= ColoursUsed[result$clusters]) 
     }) 
     }) 
    } 
    }) 

    output$densityPlot <- renderUI({ 

    inFile <- input$files 
    if (is.null(inFile)) 
     return(NULL) 
    createPlots() 
    numberOfFiles <- length(inFile$datapath) 
    plot_output_list <- lapply(1:numberOfFiles, function(i) { 
     plotname <- paste("plot", i, sep="") 
     plotOutput(plotname) 
    }) 

    do.call(tagList, plot_output_list) 
    }) 

}) 
+0

Я просто хотел бы добавить, что это действительно важно, где вы размещаете createPlots() вызов внутри части renderUI. Он должен быть вызван до начала работы и do.call (tagList, ...) – user3293236

Смежные вопросы