导入文件并附加到 r shiny 中先前加载的文件
Posted
技术标签:
【中文标题】导入文件并附加到 r shiny 中先前加载的文件【英文标题】:Import file and append to previously loaded file in r shiny 【发布时间】:2019-10-11 14:31:42 【问题描述】:我正在尝试制作一个闪亮的应用程序,通过它我可以按顺序上传 excel 文件。每次我上传文件时,它都会添加到之前加载的文件中(假设它们具有相同的格式)。
我所做的是将df_all
定义为一个空数据框。每次我点击上传并选择一个文件时,我都做了bind_rows(df_all, df)
。但它没有用。
谁能帮我弄清楚我做错了什么?我花了几个小时尝试所有不同的事情,但没有成功。
# set working directory
setwd(my_working_directory)
ipak <- function(pkg)
new.pkg <- pkg[!(pkg %in% installed.packages()[, "Package"])]
if (length(new.pkg))
install.packages(new.pkg, dependencies = TRUE)
sapply(pkg, require, character.only = TRUE)
packages <- c('devtools', 'readxl',
'shiny', 'DT')
ipak(packages)
## ui
##---------------------------------------------------------------
ui <- fluidPage(
fluidRow(
column(9, h2('Import Excel'), align='center')
),
sidebarLayout(
sidebarPanel(
#----------------------Upload Files-----------------
conditionalPanel(
condition= " input.tabs == 'Upload_Files' ",
fileInput('file', 'Choose Excel file',
accept = c(".xlsx")
)
)
),
#------------------------------Main Panel------------------------
mainPanel(
tabsetPanel(
id = 'tabs',
tabPanel('Upload_Files',
fluidRow (
column(12, DT::dataTableOutput('data.table1') )
)
)
)
)
)
)
##--------------------server-----------------------
server <- function(input, output, session)
df_all = data.frame()
output$data.table1 <- DT::renderDataTable(
# input$file will be NULL initially.
req(input$file)
inFile <- input$file
if(is.null(inFile))
return(NULL)
df=read_excel(inFile$datapath)
df_all = bind_rows(df_all, df)
return(df_all)
)
runApp(shinyApp(ui=ui, server=server))
【问题讨论】:
“但它不起作用”。你能提供细节吗? R 有数百条错误消息,如果我们知道从哪条开始会容易得多。 【参考方案1】:您对df_all
的更新存在缺陷,原因有两个:
-
当您在反应块内引用
df_all
时,它会获取外部引用(在反应块之外),然后将其分配给块内的df_all
,从不更新外部引用。在某些情况下,这建议使用<<-
,尽管我不鼓励这种心态,因为它会导致有问题的编程(如果不必要,应该避免副作用)。还有...
您应该让外部 df_all
具有响应性。
相反,试试
server <- function(input, output, session)
df_all <- reactiveVal(NULL)
output$data.table1 <- DT::renderDataTable(
req(input$file)
olddf <- isolate(df_all())
if(is.null(input$file)) return(NULL)
df <- readr::read_excel(input$file$datapath)
df <- dplyr::bind_rows(olddf, df)
isolate(df_all(df))
return(df)
)
假设所有表的结构都相似,这应该可以工作。您可能希望通过一些预先检查等(确认一个存在于另一个中的名称等)来更加谨慎地进行行绑定。
顺便说一句:我使用isolate(...)
,以便重新渲染表格不会双重触发DT:renderDataTable
。这并不是说渲染不能响应 else 对 df_all
进行更改的东西,但不能响应自我强加(循环)反应。
【讨论】:
非常感谢!这样可行!对不起,还有一个问题。我还需要一个从这个过程中生成的响应式数据框,以便我稍后可以在应用程序中用于数据可视化,而不仅仅是显示数据表。我怎样才能做到这一点? @r2evans 我不明白...df_all
是一个反应框架。任何其他块中依赖于df_all()
的任何内容都应该对其更改做出反应。它的行为不是这样吗?以上是关于导入文件并附加到 r shiny 中先前加载的文件的主要内容,如果未能解决你的问题,请参考以下文章
r Shiny 使 textInput 以先前的 selectInput 为条件