运行 Shiny 脚本时如何在 R studio 控制台中显示反应矩阵值?
How to show reactive matrix values in R studio console while running Shiny script?
我正在为我昨天 post 的问题寻找解决方案,。帮助解决以下问题将帮助我找到昨天 post.
的可能解决方案
以下代码按预期工作。矩阵 1 值下游到矩阵 2 的“场景 1”,矩阵 2 允许输入其他场景,所有场景都绘制为单独的线。但是,我试图在实时“反应”的基础上将矩阵 1 和矩阵 2 的值输出到 R studio 控制台,这样我就可以在代码运行时看到矩阵值发生了什么。在下面的代码中,我用矩阵 2 (tmpMat2
) 尝试了这个但没有成功:所以我在下面的代码中注释掉了这些行,以便它运行并且有人可以帮助我走出困境。显然,那些被注释掉的行是错误的。
请问,当用户输入矩阵时,如何在 R studio 控制台中实时显示矩阵 1 (tmpMat1
) 和矩阵 2 (tmpMat2
) 的值?
代码:
library(dplyr)
library(ggplot2)
library(shiny)
library(shinyMatrix)
sumMat <- function(x){return(rep(sum(x,na.rm = TRUE), 10))}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
matrixInput("matrix1",
label ="Matrix 1 (scenario 1):",
value = matrix(c(60,5), nrow = 1, ncol = 2, dimnames = list(NULL,c("X","Y"))),
rows = list(extend = TRUE, delete = TRUE),
class = "numeric"),
matrixInput("matrix2",
label = "Matrix 2:",
value = matrix(c(60,5), ncol = 2, dimnames = list(NULL, rep("Scenario 1", 2))),
rows = list(extend = TRUE, delete = TRUE),
cols = list(extend = TRUE, delta = 2, delete = TRUE, multiheader = TRUE),
class = "numeric")
),
mainPanel(plotOutput("plot"))
)
)
server <- function(input, output, session){
# rv <- reactiveValues(tmpMat=NULL)
observeEvent(input$matrix1, {
a <- apply(input$matrix2,2,'length<-',max(nrow(input$matrix2),nrow(input$matrix1)))
b <- apply(input$matrix1,2,'length<-',max(nrow(input$matrix2),nrow(input$matrix1)))
c <- if(length(a) == 2){c(b)} else {c(b,a[,-1:-2])}
d <- ncol(input$matrix2)
tmpMat2 <- matrix(c(c), ncol = d)
colnames(tmpMat2) <- paste("Scenario",rep(1:ncol(tmpMat2),each=2,length.out=ncol(tmpMat2)))
if(any(rownames(input$matrix1) == "")){
tmpMat1 <- input$matrix1
rownames(tmpMat1) <- paste("Row", seq_len(nrow(input$matrix1)))
updateMatrixInput(session, inputId = "matrix1", value = tmpMat1)
}
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
})
observeEvent(input$matrix2, {
if(any(colnames(input$matrix2) == "")){
tmpMat2 <- input$matrix2
colnames(tmpMat2) <- paste("Scenario",rep(1:ncol(tmpMat2),each=2,length.out=ncol(tmpMat2)))
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
}
if(any(rownames(input$matrix2) == "")){
tmpMat2 <- input$matrix2
rownames(tmpMat2) <- paste("Row", seq_len(nrow(input$matrix2)))
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
}
input$matrix2
# rv$tmpMat <- tmpMat2
})
# observe({print(rv$tmpMat)})
plotData <- reactive({
tryCatch(
lapply(seq_len(ncol(input$matrix2)/2),
function(i){
tibble(
Scenario= colnames(input$matrix2)[i*2-1],X=seq_len(10),
Y=sumMat(input$matrix2[,(i*2-1):(i*2), drop = FALSE])
)
}) %>% bind_rows(),
error = function(e) NULL
)
})
output$plot <- renderPlot({
req(plotData())
plotData() %>% ggplot() +
geom_line(aes(x = X, y = Y, colour = as.factor(Scenario))) +
theme(legend.title=element_blank())
})
}
shinyApp(ui, server)
我在 server
部分添加了以下代码,其中每行末尾都用“# Added”标记了添加内容。这些代码添加,当 运行 应用程序时,显示反应对象如何随着用户输入在 RStudio 控制台中演变。虽然输出视图不是很干净。如果我可以在从一个 observe()
移动到下一个
时插入某种中断或文本标志,那就太好了。
server <- function(input, output, session){
rv <- reactiveValues(tmpMat1=NULL,tmpMat2obsMat1=NULL,tmpMat2obsMat2=NULL) # Added
observeEvent(input$matrix1, {
a <- apply(input$matrix2,2,'length<-',max(nrow(input$matrix2),nrow(input$matrix1)))
b <- apply(input$matrix1,2,'length<-',max(nrow(input$matrix2),nrow(input$matrix1)))
c <- if(length(a) == 2){c(b)} else {c(b,a[,-1:-2])}
d <- ncol(input$matrix2)
tmpMat2 <- matrix(c(c), ncol = d)
colnames(tmpMat2) <- paste("Scenario",rep(1:ncol(tmpMat2),each=2,length.out=ncol(tmpMat2)))
if(any(rownames(input$matrix1) == "")){
tmpMat1 <- input$matrix1
rownames(tmpMat1) <- paste("Row", seq_len(nrow(input$matrix1)))
updateMatrixInput(session, inputId = "matrix1", value = tmpMat1)
}
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
rv$tmpMat1 <- input$matrix1 # Added
rv$tmpMat2obsMat1 <- input$matrix2 # Added
})
observeEvent(input$matrix2, {
if(any(colnames(input$matrix2) == "")){
tmpMat2 <- input$matrix2
colnames(tmpMat2) <- paste("Scenario",rep(1:ncol(tmpMat2),each=2,length.out=ncol(tmpMat2)))
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
}
if(any(rownames(input$matrix2) == "")){
tmpMat2 <- input$matrix2
rownames(tmpMat2) <- paste("Row", seq_len(nrow(input$matrix2)))
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
}
input$matrix2
rv$tmpMat2obsMat2 <- input$matrix2 # Added
})
observe({print(rv$tmpMat1)}) # Added
observe({print(rv$tmpMat2obsMat1)}) # Added
observe({print(rv$tmpMat2obsMat2)}) # Added
plotData <- reactive({
tryCatch(
lapply(seq_len(ncol(input$matrix2)/2),
function(i){
tibble(
Scenario= colnames(input$matrix2)[i*2-1],X=seq_len(10),
Y=sumMat(input$matrix2[,(i*2-1):(i*2), drop = FALSE])
)
}) %>% bind_rows(),
error = function(e) NULL
)
})
output$plot <- renderPlot({
req(plotData())
plotData() %>% ggplot() +
geom_line(aes(x = X, y = Y, colour = as.factor(Scenario))) +
theme(legend.title=element_blank())
})
}
见上述修改post后添加的第二组代码中标有“#已添加”的行。我还在底部的服务器部分(上面未显示)添加了以下行,以便为每个反应对象生成全局变量,以便我可以在 运行 代码(有助于调试)之后查看结束值:
oe1 <- reactive({
rv$tmpMat1})
observeEvent(oe1(),{tmpMat1.R <<- oe1()})
oe2 <- reactive({
rv$tmpMat2obsMat1})
observeEvent(oe2(),{tmpMat2obsMat1.R <<- oe2()})
oe3 <- reactive({
rv$tmpMat2obsMat2})
observeEvent(oe3(),{tmpMat2obsMat2.R <<- oe3()})
我正在为我昨天 post 的问题寻找解决方案,
以下代码按预期工作。矩阵 1 值下游到矩阵 2 的“场景 1”,矩阵 2 允许输入其他场景,所有场景都绘制为单独的线。但是,我试图在实时“反应”的基础上将矩阵 1 和矩阵 2 的值输出到 R studio 控制台,这样我就可以在代码运行时看到矩阵值发生了什么。在下面的代码中,我用矩阵 2 (tmpMat2
) 尝试了这个但没有成功:所以我在下面的代码中注释掉了这些行,以便它运行并且有人可以帮助我走出困境。显然,那些被注释掉的行是错误的。
请问,当用户输入矩阵时,如何在 R studio 控制台中实时显示矩阵 1 (tmpMat1
) 和矩阵 2 (tmpMat2
) 的值?
代码:
library(dplyr)
library(ggplot2)
library(shiny)
library(shinyMatrix)
sumMat <- function(x){return(rep(sum(x,na.rm = TRUE), 10))}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
matrixInput("matrix1",
label ="Matrix 1 (scenario 1):",
value = matrix(c(60,5), nrow = 1, ncol = 2, dimnames = list(NULL,c("X","Y"))),
rows = list(extend = TRUE, delete = TRUE),
class = "numeric"),
matrixInput("matrix2",
label = "Matrix 2:",
value = matrix(c(60,5), ncol = 2, dimnames = list(NULL, rep("Scenario 1", 2))),
rows = list(extend = TRUE, delete = TRUE),
cols = list(extend = TRUE, delta = 2, delete = TRUE, multiheader = TRUE),
class = "numeric")
),
mainPanel(plotOutput("plot"))
)
)
server <- function(input, output, session){
# rv <- reactiveValues(tmpMat=NULL)
observeEvent(input$matrix1, {
a <- apply(input$matrix2,2,'length<-',max(nrow(input$matrix2),nrow(input$matrix1)))
b <- apply(input$matrix1,2,'length<-',max(nrow(input$matrix2),nrow(input$matrix1)))
c <- if(length(a) == 2){c(b)} else {c(b,a[,-1:-2])}
d <- ncol(input$matrix2)
tmpMat2 <- matrix(c(c), ncol = d)
colnames(tmpMat2) <- paste("Scenario",rep(1:ncol(tmpMat2),each=2,length.out=ncol(tmpMat2)))
if(any(rownames(input$matrix1) == "")){
tmpMat1 <- input$matrix1
rownames(tmpMat1) <- paste("Row", seq_len(nrow(input$matrix1)))
updateMatrixInput(session, inputId = "matrix1", value = tmpMat1)
}
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
})
observeEvent(input$matrix2, {
if(any(colnames(input$matrix2) == "")){
tmpMat2 <- input$matrix2
colnames(tmpMat2) <- paste("Scenario",rep(1:ncol(tmpMat2),each=2,length.out=ncol(tmpMat2)))
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
}
if(any(rownames(input$matrix2) == "")){
tmpMat2 <- input$matrix2
rownames(tmpMat2) <- paste("Row", seq_len(nrow(input$matrix2)))
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
}
input$matrix2
# rv$tmpMat <- tmpMat2
})
# observe({print(rv$tmpMat)})
plotData <- reactive({
tryCatch(
lapply(seq_len(ncol(input$matrix2)/2),
function(i){
tibble(
Scenario= colnames(input$matrix2)[i*2-1],X=seq_len(10),
Y=sumMat(input$matrix2[,(i*2-1):(i*2), drop = FALSE])
)
}) %>% bind_rows(),
error = function(e) NULL
)
})
output$plot <- renderPlot({
req(plotData())
plotData() %>% ggplot() +
geom_line(aes(x = X, y = Y, colour = as.factor(Scenario))) +
theme(legend.title=element_blank())
})
}
shinyApp(ui, server)
我在 server
部分添加了以下代码,其中每行末尾都用“# Added”标记了添加内容。这些代码添加,当 运行 应用程序时,显示反应对象如何随着用户输入在 RStudio 控制台中演变。虽然输出视图不是很干净。如果我可以在从一个 observe()
移动到下一个
server <- function(input, output, session){
rv <- reactiveValues(tmpMat1=NULL,tmpMat2obsMat1=NULL,tmpMat2obsMat2=NULL) # Added
observeEvent(input$matrix1, {
a <- apply(input$matrix2,2,'length<-',max(nrow(input$matrix2),nrow(input$matrix1)))
b <- apply(input$matrix1,2,'length<-',max(nrow(input$matrix2),nrow(input$matrix1)))
c <- if(length(a) == 2){c(b)} else {c(b,a[,-1:-2])}
d <- ncol(input$matrix2)
tmpMat2 <- matrix(c(c), ncol = d)
colnames(tmpMat2) <- paste("Scenario",rep(1:ncol(tmpMat2),each=2,length.out=ncol(tmpMat2)))
if(any(rownames(input$matrix1) == "")){
tmpMat1 <- input$matrix1
rownames(tmpMat1) <- paste("Row", seq_len(nrow(input$matrix1)))
updateMatrixInput(session, inputId = "matrix1", value = tmpMat1)
}
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
rv$tmpMat1 <- input$matrix1 # Added
rv$tmpMat2obsMat1 <- input$matrix2 # Added
})
observeEvent(input$matrix2, {
if(any(colnames(input$matrix2) == "")){
tmpMat2 <- input$matrix2
colnames(tmpMat2) <- paste("Scenario",rep(1:ncol(tmpMat2),each=2,length.out=ncol(tmpMat2)))
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
}
if(any(rownames(input$matrix2) == "")){
tmpMat2 <- input$matrix2
rownames(tmpMat2) <- paste("Row", seq_len(nrow(input$matrix2)))
updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
}
input$matrix2
rv$tmpMat2obsMat2 <- input$matrix2 # Added
})
observe({print(rv$tmpMat1)}) # Added
observe({print(rv$tmpMat2obsMat1)}) # Added
observe({print(rv$tmpMat2obsMat2)}) # Added
plotData <- reactive({
tryCatch(
lapply(seq_len(ncol(input$matrix2)/2),
function(i){
tibble(
Scenario= colnames(input$matrix2)[i*2-1],X=seq_len(10),
Y=sumMat(input$matrix2[,(i*2-1):(i*2), drop = FALSE])
)
}) %>% bind_rows(),
error = function(e) NULL
)
})
output$plot <- renderPlot({
req(plotData())
plotData() %>% ggplot() +
geom_line(aes(x = X, y = Y, colour = as.factor(Scenario))) +
theme(legend.title=element_blank())
})
}
见上述修改post后添加的第二组代码中标有“#已添加”的行。我还在底部的服务器部分(上面未显示)添加了以下行,以便为每个反应对象生成全局变量,以便我可以在 运行 代码(有助于调试)之后查看结束值:
oe1 <- reactive({
rv$tmpMat1})
observeEvent(oe1(),{tmpMat1.R <<- oe1()})
oe2 <- reactive({
rv$tmpMat2obsMat1})
observeEvent(oe2(),{tmpMat2obsMat1.R <<- oe2()})
oe3 <- reactive({
rv$tmpMat2obsMat2})
observeEvent(oe3(),{tmpMat2obsMat2.R <<- oe3()})