导入文件并附加到 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,从不更新外部引用。在某些情况下,这建议使用&lt;&lt;-,尽管我不鼓励这种心态,因为它会导致有问题的编程(如果不必要,应该避免副作用)。还有... 您应该让外部 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。这并不是说渲染不能响应 elsedf_all 进行更改的东西,但不能响应自我强加(循环)反应。

【讨论】:

非常感谢!这样可行!对不起,还有一个问题。我还需要一个从这个过程中生成的响应式数据框,以便我稍后可以在应用程序中用于数据可视化,而不仅仅是显示数据表。我怎样才能做到这一点? @r2evans 我不明白...df_all 是一个反应框架。任何其他块中依赖于df_all() 的任何内容都应该对其更改做出反应。它的行为不是这样吗?

以上是关于导入文件并附加到 r shiny 中先前加载的文件的主要内容,如果未能解决你的问题,请参考以下文章

R Shiny 加速数据加载

r Shiny 使 textInput 以先前的 selectInput 为条件

通过 R Shiny 中的先前输入限制输入的选项

R Shiny Server - 在应用程序启动时设置加载动画

R Shiny:如何动态附加任意数量的输入小部件

为啥我的 jpg 和 png 没有在 R Shiny 上处理? [复制]