【发布时间】:2021-11-09 07:50:34
【问题描述】:
在运行以下 MWE 代码时,在 R Studio 控制台框中,我收到警告“如果:参数长度为 0 时出错”,尽管应用程序实际上继续正常运行。我究竟做错了什么?如何消除这种情况?
这是应用程序的工作原理。如下图第一张所示,用户可以改变滑块中的周期 Y 和侧边栏面板中显示的输入框中的基值级别 Z。基值源自 MWE 中的 matrix1...。如图 2 所示,用户可以对变量 Y 和 Z 进行进一步的更改,包括更改 Z 值曲线形状,方法是单击“显示”操作按钮并更改弹出的矩阵输入网格。第二个矩阵网格源自matrix2,如您所见,这两个矩阵与matrix2 链接,取代matrix1。 (注意:先对右列进行任何矩阵输入更改,然后对左列进行更改;这是由于 shinyMatrix 中的一个小错误,我需要下载修复程序)。
MWE 代码:
library(shiny)
library(shinyMatrix)
library(shinyjs)
matrix1Input <- function(x){
matrixInput(x,
value = matrix(c(0.2), 1, 1, dimnames = list(c("Z"),NULL)),
rows = list(extend = FALSE, names = TRUE),
cols = list(extend = FALSE, names = FALSE, editableNames = FALSE),
class = "numeric")}
matrix2Input <- function(x,y,z){ # x = label, y = period, z = value in period y
matrixInput(x,
value = matrix(c(y,z),1,2,dimnames=list(NULL,c("Y","Z"))),
rows = list(extend = TRUE, names = FALSE),
cols = list(extend = FALSE, names = TRUE, editableNames = FALSE),
class = "numeric")}
matrixLink <- function(x,y){
observeEvent(input$periods|input$base_input,{
updateMatrixInput(session,x,value=matrix(c(input$periods,y),1,2,dimnames=list(NULL, c("y","z"))))
})} # close observe event and function
matrixValidate <- function(x,y){ # x = time period x, y = matrix inputs
a <- y
a[,1][a[,1]>x] <- x
b <- diff(a[,1,drop=FALSE])
b[b<=0] <- NA
b <- c(1,b)
a <- cbind(a,b)
a <- na.omit(a)
a <- a[,-c(3),drop=FALSE]
return(a)}
# --- Spreads matrix1 input across even time horizon of periods x --- #
vectorBase <- function(x,y){ # x = periods, y = value to spread over periods x
a <- rep(y,x)
b <- seq(1:x)
c <- data.frame(x = b, y = a)
return(c)}
# --- Interpolates & spreads matrix2 input across even time horizon --- #
vectorMulti <- function(x,y,z){ # x = total periods, y = period, z = value to apply in period y
a <- rep(NA, x)
a[y] <- z
a[seq_len(min(y)-1)] <- a[min(y)]
if(max(y) < x){a[seq(max(y)+1, x, 1)] <- 0}
a <- approx(seq_along(a)[!is.na(a)],a[!is.na(a)],seq_along(a))$y
b <- seq(1:x)
c <- data.frame(x=b,z=a)
return(c)}
# --- Runs vectorMulti raw inputs through matrixValidate to output clean vector data --- #
vectorMultiFinal <- function(x,y){ # x = periods, y = matrix input
vectorMulti(x,matrixValidate(x,y)[,1],matrixValidate(x,y)[,2])}
vectorPlot <- function(w,x,y,z){plot(w,main=x,xlab=y,ylab=z)}
ui <- pageWithSidebar(
headerPanel("Model..."),
sidebarPanel(uiOutput("Panels")),
mainPanel(
tabsetPanel(
tabPanel("Balances", value=2,
fluidRow(
radioButtons(
inputId = 'Tab2',
label = h5(strong(helpText("View:"))),
choices = c('Vector plot'),
selected = 'Vector plot',
inline = TRUE
) # close radio buttons
), # close fluid row
conditionalPanel(condition="input.Tab2=='Vector plot'",plotOutput("graph1")),
), # close tab panel
id = "tabselected"
) # close tabset panel
) # close main panel
) # close page with sidebar
server <- function(input,output,session)({
periods <- reactive(input$periods)
base_input <- reactive(input$base_input)
yield_input <- reactive(input$yield_input)
showResults <- reactiveValues()
vectorVariable <- function(x,y){
if(input$showVectorBtn == 0) vectorBase(input$periods,x)
else vectorMultiFinal(input$periods,matrixValidate(input$periods,y))}
yield <- function(){vectorVariable(input$base_input[1,1],yield_input())}
output$Panels <- renderUI({
tagList(
conditionalPanel(
condition="input.tabselected==2",
sliderInput('periods','Periods Y:',min=1,max=30,value=15),
helpText(strong('Change variable Z below:')),
matrix1Input("base_input"),
useShinyjs(),
helpText(strong('Add curve to variable Z:')),
actionButton('showVectorBtn','Show'),
actionButton('hideVectorBtn','Hide'),
actionButton('resetVectorBtn','Reset'),
hidden(uiOutput("Vectors"))
), # close conditional panel
) # close tagList
}) # close renderUI
renderUI({matrixLink("yield_input",input$base_input[1,1])})
vectorsAll <- reactive({cbind(Period = 1:periods(),Yld_Rate = yield()[,2])})
observeEvent(input$showVectorBtn,{shinyjs::show("Vectors")})
observeEvent(input$hideVectorBtn,{shinyjs::hide("Vectors")})
observeEvent(input$showVectorPlotBtn,{showResults$showme <- plotOutput("graph1")},ignoreNULL = FALSE)
output$Vectors <- renderUI({
input$resetVectorBtn
matrix2Input("yield_input",input$periods,input$base_input[1,1])
}) # close render UI
output$graph1 <-renderPlot(vectorPlot(yield(),"","Period","Rate"))
output$showResults <- renderUI({showResults$showme})
}) # close server
shinyApp(ui, server)
【问题讨论】:
-
也需要
matrixInput函数 -
嗨猪排,matrixInput 是 shinyMatrix 包的一部分
标签: r shiny shiny-reactivity