解决错误,我在R / RMd / Shiny中不知道

时间:2020-04-22 22:05:24

标签: r ggplot2 shiny r-markdown plotly

我正在使用RMarkdown和ShinyApp编写交互式HTML文档。我遇到问题的部分应该为三种不同的概率分布(用户输入)获取参数,并输出随图形而变化的绘图。该图有3条线,每种概率分布各一条。我得到的错误是length(lower) == 1 is not TRUE

服务器/用户界面代码如下:

suppressWarnings(suppressMessages(library(ggplot2)))
suppressWarnings(suppressMessages(library(plotly)))
suppressWarnings(suppressMessages(library(tidyverse)))
suppressWarnings(suppressMessages(library(VGAM)))
source("mk_functions.R")

# UI ----
fluidPage(
  titlePanel("Graphs"),

  sidebarLayout(
    sidebarPanel(
      numericInput("alpha", "Pareto alpha", value = 1.5, min = 1, 
                   step = 0.2),
      numericInput("scalePareto", "Pareto scale", value = 1, min = 0,
                   step = 0.2),
      numericInput("lambda", "Exponential lambda", value = 1, min = 0, 
                   step = 0.2),
      numericInput("mean", "Folded Gaussian mean", value = 0, 
                   step = 0.2),
      numericInput("sd", "Folded Gaussian sigma", value = 1, min = 0, 
                   step = 0.2)),


    mainPanel(plotlyOutput("paretoPlot"))
  )
)

# Server ----
output$paretoPlot = renderPlotly({

  withProgress(message = "Progress:", expr={

    N = 1e03
    data = data.frame(p = c(1:N)/N)

    for (i in 1:nrow(data)){
      data[['Folded Gaussian']][i] = mk_foldnorm(data[['p']][i],
                                                 mean = input$mean,
                                                 sd = input$sd)
      data[['Exponential']][i] = mk_exponential(data[['p']][i],
                                                rate = input$rate)
      data[['Pareto']][i] = mk_pareto(data[['p']][i],
                                      shape = input$alpha,
                                      scale = input$scalePareto)
      incProgress(1/(nrow(shannon_portf)-1), 
                  message = paste("Progress: ", 
                                  round(100*i/nrow(data)), 
                                  "%", sep=""))
    }

  })


  data = data %>% 
    pivot_longer(-p, names_to = "Distribution", values_to = "mk", -p)

  plt = ggplot(data, aes(p, mk)) + 
    geom_line(aes(color=Distribution)) + 
    theme_bw()

  plt = ggplotly(plt)
  plt

})

我已经在示例输入(实际上与初始输入值相同)的一侧运行了此代码,并且效果很好。 VGAM包在"mk_functions.R"文件中使用。供参考,这是文件"mk_functions.R"(简短):

mk_foldnorm = function(p, mean=0, sd=1){
  k = qfoldnorm(1-p, mean = mean, sd = sd)
  f = function(x) x*dfoldnorm(x, mean = mean, sd = sd)
  numerator = integrate(f = f, lower = k, upper = Inf) 
  denominator = integrate(f = f, lower = -Inf, upper = Inf)
  mk = numerator$value / denominator$value
  print(mk)
}

mk_pareto = function(p, shape, scale=1){
  k = qpareto(1-p, scale = scale, shape = shape)
  f = function(x) x*dpareto(x, scale = scale, shape = shape)
  numerator = integrate(f = f, lower = k, upper = Inf) 
  denominator = integrate(f = f, lower = -Inf, upper = Inf)
  mk = numerator$value / denominator$value
  print(mk)
}

mk_exponential = function(p, rate=1){
  k = qexp(1-p, rate = rate)
  f = function(x) x*dexp(x, rate = rate)
  numerator = integrate(f = f, lower = k, upper = Inf) 
  denominator = integrate(f = f, lower = -Inf, upper = Inf)
  mk = numerator$value / denominator$value
  print(mk)
}

同样,错误为length(lower) == 1 is not TRUE。我尝试更改integrate(...)的下限,但这不会更改输出。我尝试输出正常的ggplot2图,但它也不会改变输出。我还没有在网上找到任何东西,几乎没有其他要调试的东西了。

我尝试更新所有软件包,甚至卸载了R和RStudio并重新安装了它们。依然没有。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您的代码似乎有几个问题:

  • shannon_portf不存在
  • input$rate不存在;但是input$lambda确实
  • pivot_longer语句返回错误-也许您想按p排序?
  • 源文件中的函数应返回值(return(mk)),而不是将其打印到控制台(print(mk)

下面是一个给出情节的版本;您可能仍需要对其进行一些调整...有些滑块似乎什么也没做,并且您可以隔离不需要重做的计算。

suppressWarnings(suppressMessages(invisible(
    lapply(c("ggplot2", "plotly", "tidyverse", "VGAM", "shiny"),
           require, character.only = TRUE))))
source("mk_functions.R")

# UI ----
ui <- shinyUI(fluidPage(
    titlePanel("Graphs"),

    sidebarLayout(
        sidebarPanel(
            numericInput("alpha", "Pareto alpha", value = 1.5, min = 1, 
                         step = 0.2),
            numericInput("scalePareto", "Pareto scale", value = 1, min = 0,
                         step = 0.2),
            numericInput("rate", "Exponential lambda", value = 1, min = 0, 
                         step = 0.2),
            numericInput("mean", "Folded Gaussian mean", value = 0, 
                         step = 0.2),
            numericInput("sd", "Folded Gaussian sigma", value = 1, min = 0, 
                         step = 0.2)),

        mainPanel(plotlyOutput("paretoPlot"))
    )
)
)

server <- shinyServer(function(input, output, session){
    # Server ----

    calcPareto <- reactive({
        withProgress(message = "Progress:", expr={

            N = 1e03
            data = data.frame(p = c(1:N)/N)

            for (i in 1:nrow(data)){
                data[['Folded Gaussian']][i] = mk_foldnorm(data[['p']][i],
                                                           mean = input$mean,
                                                           sd = input$sd)
                data[['Exponential']][i] = mk_exponential(data[['p']][i],
                                                          rate = input$rate)
                data[['Pareto']][i] = mk_pareto(data[['p']][i],
                                                shape = input$alpha,
                                                scale = input$scalePareto)
                incProgress(1/(nrow(data)-1), 
                            message = paste("Progress: ", 
                                            round(100*i/nrow(data)), 
                                            "%", sep=""))
            }


        })
        return(data)
    })

    output$paretoPlot = renderPlotly({
        req(calcPareto())
        data = calcPareto() %>% 
            pivot_longer(-p, names_to = "Distribution", values_to = "mk") %>% 
            dplyr::arrange(-p)

        plt = ggplot(data, aes(p, mk)) + 
            geom_line(aes(color=Distribution)) + 
            theme_bw()

        plt = ggplotly(plt)
        plt

    })

})

shinyApp(ui = ui, server = server)