使用在 Shiny 服务器中构建的数据框用于两个输出
Using a dataframe built within a Shiny server for two outputs
我正在开发一个简单的 Shiny 应用程序来可视化方差分析(总计、组间、组内)的变异来源。基本上,我希望用户为三组单向方差分析场景输入 "group n"、"means" 和 "sds" - 然后,该应用程序生成一个数据集来创建一个图和一个相应的方差分析 table。
我无法弄清楚如何在用户更改输入参数时同时更新绘图和方差分析 table。我的大部分尝试都导致了更新的情节,但 table 没有。
我最接近实际解决方案的是下面的 "hack-y/cheating" 方法,其中同一数据集生成两次。然而,这显然是不必要的。我假设该解决方案与在服务器函数中创建一个 "reactive" 数据集有关,该数据集可以用于多个输出。从原则上讲,这似乎应该是一件相当简单的事情。但是,我无法在网上拼凑 tutorials/materials 来弄清楚如何去做。如有任何帮助,我们将不胜感激。
代码:
# Visualizing partitioning variance for oneway ANOVA
library(shiny)
ui <- fluidPage(
titlePanel("Partitioning Variance in a Oneway ANOVA"),
sidebarLayout(
sidebarPanel(
sliderInput("N", "n for each group:",
min = 2, max = 50, value = 25),
sliderInput("M1", "Mean for Control Group:",
min = 1, max = 100, value = 55),
sliderInput("SD1", "SD for Control Group:",
min = 1, max = 20, value = 10),
sliderInput("M2", "Mean for Treatment Group One:",
min = 1, max = 100, value = 55),
sliderInput("SD2", "SD for Treatment Group One:",
min = 1, max = 20, value = 10),
sliderInput("M3", "Mean for Treatment Group Two:",
min = 1, max = 100, value = 55),
sliderInput("SD3", "SD for Treatment Group Two:",
min = 1, max = 20, value = 10)
),
mainPanel(
plotOutput("varPlot"),
verbatimTextOutput("anovaTable")
)
)
)
server <- function(input, output) {
output$varPlot <- renderPlot({
set.seed(1976)
X1 <- rnorm(input$N, input$M1, input$SD1)
X2 <- rnorm(input$N, input$M2, input$SD2)
X3 <- rnorm(input$N, input$M3, input$SD3)
datOutcome = data.frame(X1, X2, X3)
library(tidyr)
dat <- gather(datOutcome, group, outcome)
dat$group <- factor(dat$group, levels = c("X1", "X2", "X3"),
labels = c("Control", "Treatment One", "Treatment Two"))
# attach the data
attach(dat)
library(car)
mod <- Anova(lm(outcome ~ group, data = dat), type = "III")
# make the stripcharts by group
stripchart(outcome ~ group, method = "jitter", jitter = 0.05,
vertical = TRUE, pch = 1, col = "blue",
group.names = c("Control", "Treatment One", "Treatment Two"),
xlim = c(.5,4.75),
ylim = c((min(dat$outcome) - 5), (max(dat$outcome) + 5)),
ylab = "Outcome Value",
main = paste("Group n =", input$N,
"\nRed = total variation, Blue = within groups variation, Green indicates between groups variation"))
# label group means
text(1.3, mean(X1),
paste("Control \nmean =", format(round(mean(X1), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
text(2.3, mean(X2),
paste("Treatment One \nmean =", format(round(mean(X2), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
text(3.3, mean(X3),
paste("Treatment Two\n mean =", format(round(mean(X3), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
# add diamonds to indicate the means for each group
points(1, mean(X1), pch = 18, cex = 2, col = "darkgreen")
points(2, mean(X2), pch = 18, cex = 2, col = "darkgreen")
points(3, mean(X3), pch = 18, cex = 2, col = "darkgreen")
# plot a stripchart for the grand mean
stripchart( outcome, method="jitter" , jitter=0.05 ,
vertical=TRUE , pch=1 , col="red" ,
at = 4, add = TRUE,
xlim=c(.5,3.75))
# label grand mean and add dimaond to indicate mean
text(4.3, mean(outcome),
paste("Grand \nmean =", format(round(mean(outcome), 2), nsmall = 2)),
col = "red", cex = .9)
points(4, mean(outcome), pch = 18, cex = 2)
})
output$anovaTable <- renderPrint( {
set.seed(1976)
X1 <- rnorm(input$N, input$M1, input$SD1)
X2 <- rnorm(input$N, input$M2, input$SD2)
X3 <- rnorm(input$N, input$M3, input$SD3)
datOutcome = data.frame(X1, X2, X3)
library(tidyr)
dat <- gather(datOutcome, group, outcome)
dat$group <- factor(dat$group, levels = c("X1", "X2", "X3"),
labels = c("Control", "Treatment One", "Treatment Two"))
A <- Anova(aov(outcome ~ group, data = dat), type = "III")
A
})
}
shinyApp(ui = ui, server = server)
这可以使用 "reactive" 范式解决
library(shiny)
library(tidyr)
ui <- fluidPage(
titlePanel("Partitioning Variance in a Oneway ANOVA"),
sidebarLayout(
sidebarPanel(
sliderInput("N", "n for each group:",
min = 2, max = 50, value = 25),
sliderInput("M1", "Mean for Control Group:",
min = 1, max = 100, value = 55),
sliderInput("SD1", "SD for Control Group:",
min = 1, max = 20, value = 10),
sliderInput("M2", "Mean for Treatment Group One:",
min = 1, max = 100, value = 55),
sliderInput("SD2", "SD for Treatment Group One:",
min = 1, max = 20, value = 10),
sliderInput("M3", "Mean for Treatment Group Two:",
min = 1, max = 100, value = 55),
sliderInput("SD3", "SD for Treatment Group Two:",
min = 1, max = 20, value = 10)
),
mainPanel(
plotOutput("varPlot"),
verbatimTextOutput("anovaTable")
)
)
)
server <- function(input, output) {
myReactiveDat <- reactive({
if(is.null(input$N)){
return(NULL)
}
set.seed(1976)
X1 <- rnorm(input$N, input$M1, input$SD1)
X2 <- rnorm(input$N, input$M2, input$SD2)
X3 <- rnorm(input$N, input$M3, input$SD3)
datOutcome = data.frame(X1, X2, X3)
dat <- gather(datOutcome, group, outcome)
dat$group <- factor(dat$group, levels = c("X1", "X2", "X3"),
labels = c("Control", "Treatment One", "Treatment Two"))
res <- list(dat=dat, X1=X1, X2=X2, X3=X3)
})
output$varPlot <- renderPlot({
res <- myReactiveDat()
if(is.null(res)){
return()
}
# attach the data
dat <- res$dat
attach(dat)
library(car)
mod <- Anova(lm(outcome ~ group, data = dat), type = "III")
# make the stripcharts by group
stripchart(outcome ~ group, method = "jitter", jitter = 0.05,
vertical = TRUE, pch = 1, col = "blue",
group.names = c("Control", "Treatment One", "Treatment Two"),
xlim = c(.5,4.75),
ylim = c((min(dat$outcome) - 5), (max(dat$outcome) + 5)),
ylab = "Outcome Value",
main = paste("Group n =", input$N,
"\nRed = total variation, Blue = within groups variation, Green indicates between groups variation"))
# label group means
text(1.3, mean(res$X1),
paste("Control \nmean =", format(round(mean(res$X1), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
text(2.3, mean(res$X2),
paste("Treatment One \nmean =", format(round(mean(res$X2), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
text(3.3, mean(res$X3),
paste("Treatment Two\n mean =", format(round(mean(res$X3), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
# add diamonds to indicate the means for each group
points(1, mean(res$X1), pch = 18, cex = 2, col = "darkgreen")
points(2, mean(res$X2), pch = 18, cex = 2, col = "darkgreen")
points(3, mean(res$X3), pch = 18, cex = 2, col = "darkgreen")
# plot a stripchart for the grand mean
stripchart( outcome, method="jitter" , jitter=0.05 ,
vertical=TRUE , pch=1 , col="red" ,
at = 4, add = TRUE,
xlim=c(.5,3.75))
# label grand mean and add dimaond to indicate mean
text(4.3, mean(outcome),
paste("Grand \nmean =", format(round(mean(outcome), 2), nsmall = 2)),
col = "red", cex = .9)
points(4, mean(outcome), pch = 18, cex = 2)
})
output$anovaTable <- renderPrint( {
res <- myReactiveDat()
if(is.null(res)){
return()
}
A <- Anova(aov(outcome ~ group, data = res$dat), type = "III")
A
})
}
shinyApp(ui = ui, server = server)
我正在开发一个简单的 Shiny 应用程序来可视化方差分析(总计、组间、组内)的变异来源。基本上,我希望用户为三组单向方差分析场景输入 "group n"、"means" 和 "sds" - 然后,该应用程序生成一个数据集来创建一个图和一个相应的方差分析 table。
我无法弄清楚如何在用户更改输入参数时同时更新绘图和方差分析 table。我的大部分尝试都导致了更新的情节,但 table 没有。
我最接近实际解决方案的是下面的 "hack-y/cheating" 方法,其中同一数据集生成两次。然而,这显然是不必要的。我假设该解决方案与在服务器函数中创建一个 "reactive" 数据集有关,该数据集可以用于多个输出。从原则上讲,这似乎应该是一件相当简单的事情。但是,我无法在网上拼凑 tutorials/materials 来弄清楚如何去做。如有任何帮助,我们将不胜感激。
代码:
# Visualizing partitioning variance for oneway ANOVA
library(shiny)
ui <- fluidPage(
titlePanel("Partitioning Variance in a Oneway ANOVA"),
sidebarLayout(
sidebarPanel(
sliderInput("N", "n for each group:",
min = 2, max = 50, value = 25),
sliderInput("M1", "Mean for Control Group:",
min = 1, max = 100, value = 55),
sliderInput("SD1", "SD for Control Group:",
min = 1, max = 20, value = 10),
sliderInput("M2", "Mean for Treatment Group One:",
min = 1, max = 100, value = 55),
sliderInput("SD2", "SD for Treatment Group One:",
min = 1, max = 20, value = 10),
sliderInput("M3", "Mean for Treatment Group Two:",
min = 1, max = 100, value = 55),
sliderInput("SD3", "SD for Treatment Group Two:",
min = 1, max = 20, value = 10)
),
mainPanel(
plotOutput("varPlot"),
verbatimTextOutput("anovaTable")
)
)
)
server <- function(input, output) {
output$varPlot <- renderPlot({
set.seed(1976)
X1 <- rnorm(input$N, input$M1, input$SD1)
X2 <- rnorm(input$N, input$M2, input$SD2)
X3 <- rnorm(input$N, input$M3, input$SD3)
datOutcome = data.frame(X1, X2, X3)
library(tidyr)
dat <- gather(datOutcome, group, outcome)
dat$group <- factor(dat$group, levels = c("X1", "X2", "X3"),
labels = c("Control", "Treatment One", "Treatment Two"))
# attach the data
attach(dat)
library(car)
mod <- Anova(lm(outcome ~ group, data = dat), type = "III")
# make the stripcharts by group
stripchart(outcome ~ group, method = "jitter", jitter = 0.05,
vertical = TRUE, pch = 1, col = "blue",
group.names = c("Control", "Treatment One", "Treatment Two"),
xlim = c(.5,4.75),
ylim = c((min(dat$outcome) - 5), (max(dat$outcome) + 5)),
ylab = "Outcome Value",
main = paste("Group n =", input$N,
"\nRed = total variation, Blue = within groups variation, Green indicates between groups variation"))
# label group means
text(1.3, mean(X1),
paste("Control \nmean =", format(round(mean(X1), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
text(2.3, mean(X2),
paste("Treatment One \nmean =", format(round(mean(X2), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
text(3.3, mean(X3),
paste("Treatment Two\n mean =", format(round(mean(X3), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
# add diamonds to indicate the means for each group
points(1, mean(X1), pch = 18, cex = 2, col = "darkgreen")
points(2, mean(X2), pch = 18, cex = 2, col = "darkgreen")
points(3, mean(X3), pch = 18, cex = 2, col = "darkgreen")
# plot a stripchart for the grand mean
stripchart( outcome, method="jitter" , jitter=0.05 ,
vertical=TRUE , pch=1 , col="red" ,
at = 4, add = TRUE,
xlim=c(.5,3.75))
# label grand mean and add dimaond to indicate mean
text(4.3, mean(outcome),
paste("Grand \nmean =", format(round(mean(outcome), 2), nsmall = 2)),
col = "red", cex = .9)
points(4, mean(outcome), pch = 18, cex = 2)
})
output$anovaTable <- renderPrint( {
set.seed(1976)
X1 <- rnorm(input$N, input$M1, input$SD1)
X2 <- rnorm(input$N, input$M2, input$SD2)
X3 <- rnorm(input$N, input$M3, input$SD3)
datOutcome = data.frame(X1, X2, X3)
library(tidyr)
dat <- gather(datOutcome, group, outcome)
dat$group <- factor(dat$group, levels = c("X1", "X2", "X3"),
labels = c("Control", "Treatment One", "Treatment Two"))
A <- Anova(aov(outcome ~ group, data = dat), type = "III")
A
})
}
shinyApp(ui = ui, server = server)
这可以使用 "reactive" 范式解决
library(shiny)
library(tidyr)
ui <- fluidPage(
titlePanel("Partitioning Variance in a Oneway ANOVA"),
sidebarLayout(
sidebarPanel(
sliderInput("N", "n for each group:",
min = 2, max = 50, value = 25),
sliderInput("M1", "Mean for Control Group:",
min = 1, max = 100, value = 55),
sliderInput("SD1", "SD for Control Group:",
min = 1, max = 20, value = 10),
sliderInput("M2", "Mean for Treatment Group One:",
min = 1, max = 100, value = 55),
sliderInput("SD2", "SD for Treatment Group One:",
min = 1, max = 20, value = 10),
sliderInput("M3", "Mean for Treatment Group Two:",
min = 1, max = 100, value = 55),
sliderInput("SD3", "SD for Treatment Group Two:",
min = 1, max = 20, value = 10)
),
mainPanel(
plotOutput("varPlot"),
verbatimTextOutput("anovaTable")
)
)
)
server <- function(input, output) {
myReactiveDat <- reactive({
if(is.null(input$N)){
return(NULL)
}
set.seed(1976)
X1 <- rnorm(input$N, input$M1, input$SD1)
X2 <- rnorm(input$N, input$M2, input$SD2)
X3 <- rnorm(input$N, input$M3, input$SD3)
datOutcome = data.frame(X1, X2, X3)
dat <- gather(datOutcome, group, outcome)
dat$group <- factor(dat$group, levels = c("X1", "X2", "X3"),
labels = c("Control", "Treatment One", "Treatment Two"))
res <- list(dat=dat, X1=X1, X2=X2, X3=X3)
})
output$varPlot <- renderPlot({
res <- myReactiveDat()
if(is.null(res)){
return()
}
# attach the data
dat <- res$dat
attach(dat)
library(car)
mod <- Anova(lm(outcome ~ group, data = dat), type = "III")
# make the stripcharts by group
stripchart(outcome ~ group, method = "jitter", jitter = 0.05,
vertical = TRUE, pch = 1, col = "blue",
group.names = c("Control", "Treatment One", "Treatment Two"),
xlim = c(.5,4.75),
ylim = c((min(dat$outcome) - 5), (max(dat$outcome) + 5)),
ylab = "Outcome Value",
main = paste("Group n =", input$N,
"\nRed = total variation, Blue = within groups variation, Green indicates between groups variation"))
# label group means
text(1.3, mean(res$X1),
paste("Control \nmean =", format(round(mean(res$X1), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
text(2.3, mean(res$X2),
paste("Treatment One \nmean =", format(round(mean(res$X2), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
text(3.3, mean(res$X3),
paste("Treatment Two\n mean =", format(round(mean(res$X3), 2), nsmall = 2)),
col = "darkgreen", cex = .9)
# add diamonds to indicate the means for each group
points(1, mean(res$X1), pch = 18, cex = 2, col = "darkgreen")
points(2, mean(res$X2), pch = 18, cex = 2, col = "darkgreen")
points(3, mean(res$X3), pch = 18, cex = 2, col = "darkgreen")
# plot a stripchart for the grand mean
stripchart( outcome, method="jitter" , jitter=0.05 ,
vertical=TRUE , pch=1 , col="red" ,
at = 4, add = TRUE,
xlim=c(.5,3.75))
# label grand mean and add dimaond to indicate mean
text(4.3, mean(outcome),
paste("Grand \nmean =", format(round(mean(outcome), 2), nsmall = 2)),
col = "red", cex = .9)
points(4, mean(outcome), pch = 18, cex = 2)
})
output$anovaTable <- renderPrint( {
res <- myReactiveDat()
if(is.null(res)){
return()
}
A <- Anova(aov(outcome ~ group, data = res$dat), type = "III")
A
})
}
shinyApp(ui = ui, server = server)