我正在使用RMarkdown和ShinyApp编写交互式HTML文档。我遇到问题的部分应该采用三种不同概率分布的参数(用户输入),并输出根据图表而变化的绘图。该图有3条线,每种概率分布各一条。我得到的错误是length(lower) == 1 is not TRUE
。
服务器/ ui代码如下:
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并重新安装了它们。依然没有。非常感谢您的帮助。
您的代码中似乎有几个问题:
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)