r - 有没有更优雅的方式在 R Shiny 中动态创建变量?
问题描述
我正在开发一个 R Shiny 应用程序,它允许用户以交互方式研究线性回归模型的简单原理。我的代码运行得很好。但是,它不是很优雅。在下面找到用于说明的服务器函数(为方便起见,我将ui
和个人定义的函数省略了,但如果您想查看它们,请告诉我):
#### Make Server ####
server = function(input, output) {
#if the users presses submit:
#take the input, format it, and forward it to 'simulation'
#which creates a dataframe(column1 = simulated response, column2 = group)
simulate <- eventReactive(input$submit, {
group1 = as.numeric(c(input$n1, input$mean1, input$sd1))
group2 = as.numeric(c(input$n2, input$mean2, input$sd2))
group3 = as.numeric(c(input$n3, input$mean3, input$sd3))
all_groups = list(group1, group2, group3)
data = simulation(all_groups)
})
#model a linear regression based on the simulated data, print the output
output$model <- renderPrint({
data = simulate()
model = lm(response ~ group,
contrasts = list(group = "contr.sum"),
data = data)
summary(model)
})
#plot density plots for every group in one graph
#add the intercepts/coefficients returned by the linear regression to that graph
output$hist <- renderPlot({
data = simulate()
model = lm(response ~ group,
contrasts = list(group = "contr.sum"),
data = data)
intercept = model[["coefficients"]][["(Intercept)"]]
intercept_g1 = model[["coefficients"]][["group1"]]
intercept_g2 = model[["coefficients"]][["group2"]]
ggplot(data, aes(x=response, fill=group)) +
geom_density(data = subset(data, group="group1"), alpha=.5) +
geom_density(data = subset(data, group="group2"), alpha=.5) +
geom_density(data = subset(data, group="group3"), alpha=.5) +
geom_vline(xintercept=intercept) +
geom_vline(xintercept=intercept_g1) +
geom_vline(xintercept=intercept_g2)
})
#if the user presses 'reset', reset all input panels to their default value
observeEvent(input$reset, {
shinyjs::reset("side-panel")
})
}
困扰我的两个主要问题是:
两者,
renderPlot
并在它们的第一行中renderPrint
创建data
变量(并且data
也在 中创建eventReacitve
)。是否可以在用户点击提交按钮时创建一次“数据”(此处未显示其实现)?两者,
renderPlot
并renderPrint
计算线性回归模型。虽然第一个只需要输出,但第二个需要一些存储在 lme 变量中的值(这里是截距)。这里也可以只计算一次模型吗?
如果您建议改进代码也可以解决其他问题,请告诉我。这只是更大项目的一小部分;将为用户添加几个选项,高效且易于维护的代码将非常有用!
解决方案
我意识到这可能不是最详尽或令人费解的答案(而且我没有足够的声誉来简单地评论),但作为一般方法,我建议您将所有步骤总结为不同的功能。例如,如果我没看错,您的renderPlot()
调用仅取决于simulate()
,而其余计算均基于 提供的数据simulate()
。因此,您可以将其总结为
plot_data <- function(data_input) {
data = data_input
model = lm(response ~ group,
contrasts = list(group = "contr.sum"),
data = data)
intercept = model[["coefficients"]][["(Intercept)"]]
intercept_g1 = model[["coefficients"]][["group1"]]
intercept_g2 = model[["coefficients"]][["group2"]]
ggplot(data, aes(x=response, fill=group)) +
geom_density(data = subset(data, group="group1"), alpha=.5) +
geom_density(data = subset(data, group="group2"), alpha=.5) +
geom_density(data = subset(data, group="group3"), alpha=.5) +
geom_vline(xintercept=intercept) +
geom_vline(xintercept=intercept_g1) +
geom_vline(xintercept=intercept_g2)
}
这将减少您对
output$hist <- renderPlot({plot_data(simulate())})
此外,在闪亮的应用程序之外编写这些函数还可以让您在通用 R 环境中更轻松地测试和调试它们,同时您可以专注于服务器函数中的应用程序。
推荐阅读
- python-3.x - 在 Python 中用矩阵绘制函数
- mysql - 将数据库从 docker 备份到真机
- django - 如何使用 react 和 axios 将 GET 请求标头中的数据发送到 Django REST 框架?
- twilio - 在 FusionPBX 上使用 Twilio SIP 中继
- javascript - javascript秒表用户输入
- python - 使用训练数据进行预测
- python - 在 Mac OS Mojave 上安装 pycuda 时出错:错误:命令“clang”失败,退出状态为 1
- css - 如何减少 sap.ui.table 单元格周围的空间
- flutter - Flutter 错误:使用不包含 MediaQuery 的上下文调用 MediaQuery.of()
- amazon-web-services - AWS Android Cognito SDK 返回“用户名或密码不正确”