在Shiny应用程序中绘制到条形图时,生成的数据框仅可用于第一个图,而第二个图则不可用(“错误:找不到对象df2”)。将代码复制和粘贴以生成数据帧到第二个renderPlot部分可以解决此问题,但是这是多余的,并且会降低应用程序的速度。有没有更优雅的方法来使数据可对应多个renderPlot零件?我尝试使用Shinys的react()函数,但没有成功。
这是一个最小的例子:
library(shiny)
library(ggplot2)
# Define UI for application that draws a histogram
ui <- fluidPage(
titlePanel("Utility"),
sidebarLayout(
sidebarPanel(
sliderInput("var1",
"N",
min = 1,
max = 100,
value = 20)),
mainPanel(
plotOutput("barplot1"),
plotOutput("barplot2"))))
# Define server logic required to draw a barplot
server <- function(input, output) {
output$barplot1 <- renderPlot({
df <- as.data.frame(matrix(c(
"A", "1", rnorm(1, input$var1, 1),
"A", "2", rnorm(1, input$var1, 1),
"B", "1", rnorm(1, input$var1, 1),
"B", "2", rnorm(1, input$var1, 1)),
nrow = 4, ncol=3, byrow = TRUE))
df$V3 <- as.numeric(as.character(df$V3))
df2 <- as.data.frame(matrix(c(
"A", "1", rnorm(1, input$var1, df[1,3]),
"A", "2", rnorm(1, input$var1, df[1,3]),
"B", "1", rnorm(1, input$var1, df[1,3]),
"B", "2", rnorm(1, input$var1, df[1,3])),
nrow = 4, ncol=3, byrow = TRUE))
df2$V3 <- as.numeric(as.character(df$V3))
ggplot(df, aes(x=V1, y=V3, fill=V2)) +
geom_bar(stat="identity")
})
output$barplot2 <- renderPlot({
ggplot(df2, aes(x=V1, y=V3, fill=V2)) +
geom_bar(stat="identity")
})
}
# Run the application
shinyApp(ui = ui, server = server)
答案 0 :(得分:0)
此人正在外面以自己的反应方式创建data.frame
library(shiny)
library(ggplot2)
# Define UI for application that draws a histogram
ui <- fluidPage(
titlePanel("Utility"),
sidebarLayout(
sidebarPanel(
sliderInput("var1",
"N",
min = 1,
max = 100,
value = 20)),
mainPanel(
plotOutput("barplot1"),
plotOutput("barplot2")
)
)
)
# Define server logic required to draw a barplot
server <- function(input, output) {
df <- reactive({
df <- as.data.frame(matrix(c(
"A", "1", rnorm(1, input$var1, 1),
"A", "2", rnorm(1, input$var1, 1),
"B", "1", rnorm(1, input$var1, 1),
"B", "2", rnorm(1, input$var1, 1)),
nrow = 4, ncol=3, byrow = TRUE))
df$V3 <- as.numeric(as.character(df$V3))
df
})
df2 <- reactive({
df2 <- as.data.frame(matrix(c(
"A", "1", rnorm(1, input$var1, df()[1,3]),
"A", "2", rnorm(1, input$var1, df()[1,3]),
"B", "1", rnorm(1, input$var1, df()[1,3]),
"B", "2", rnorm(1, input$var1, df()[1,3])
),
nrow = 4, ncol=3, byrow = TRUE))
df2$V3 <- as.numeric(as.character(df()$V3))
df2
})
output$barplot1 <- renderPlot({
ggplot( df() , aes(x=V1, y=V3, fill=V2)) +
geom_bar(stat="identity")
})
output$barplot2 <- renderPlot({
ggplot(df2(), aes(x=V1, y=V3, fill=V2)) +
geom_bar(stat="identity")
})
}
# Run the application
shinyApp(ui = ui, server = server)
答案 1 :(得分:0)
是的,您永远不应复制数据。要使您的数据框可用于所有功能,只需使用reactive
动态生成它即可(因为它取决于input$var1
)。调用反应变量x
时,您需要使用x()
而不是x
。否则,您将得到以下错误:Error: object of type 'closure' is not subsettable"
。因此,在您的情况下,使df
处于反应状态将需要您改用df()
。
server <- function(input, output) {
df <- reactive(
data.frame(V1 = c("A", "A", "B", "B"),
V2 = c("1", "2", "1", "2"),
V3 = rnorm(1, input$var1, 5)
)
)
output$barplot1 <- renderPlot({
ggplot(df(), aes(x=V1, y=V3, fill=V2)) +
geom_bar(stat="identity")
})
output$barplot2 <- renderPlot({
ggplot(df(), aes(x=V1, y=V3, fill=V2)) +
geom_bar(stat="identity")
})
}