2015-11-02 51 views
-2

你好我正在用幾個excel文件構建一個shinydashboard。如何更新文件更改的用戶界面

我在框的頁腳中插入了這些文件的鏈接,並且想要在更改excel文件中的某些內容時更新 shinydashboard的。 我不想每次都運行整個R代碼。

一旦文件內容發生變化,我該如何重新渲染輸出?

下面的例子:

sidebar <- dashboardSidebar(
sidebarMenu(menuItem("Hello", tabName = "Hello", icon = icon("dashboard")) 
     )) 

body <- dashboardBody(
tabItems(

tabItem(tabName = "Hello", 


     box(title = "my file", 
      footer = a("df.xlsx", href="df.xlsx") , 
      DT::dataTableOutput("df1"),style = "font-size: 100%; overflow: auto;", 
      width = 12, hight = NULL, solidHeader = TRUE, collapsible = TRUE, collapsed = TRUE, status = "primary") 
))) 


ui <- dashboardPage(
dashboardHeader(title = "My Dashboard"), 
sidebar, 
body) 


server <- function(input, output) { 
    output$df1 <- renderDataTable({ 
df <- read_excel("df.xlsx") 
DT::datatable(df, escape = FALSE, rownames=FALSE,class = "cell-border", 
       options =list(bSort = FALSE, paging = FALSE, info = FALSE) 
) 
    }) 
} 



shinyApp(ui, server) 
+0

你可以用tools :: md5sum來計算md5,當這個文件改變時你可以更新你的UI。看看'tcltk2 :: tclTask​​Schedule'在計時器上運行任務,或者'invalidateLater'來檢查數據是否發生了變化。 –

回答

1

爲了監視文件的變化,你可以使用的文件這樣的cheksum:

library(shiny) 
library(digest) 

# Create data to read 
write.csv(file="~/iris.csv",iris) 

shinyApp(ui=shinyUI(
    fluidPage(
    sidebarLayout(
     sidebarPanel(
     textInput("path","Enter path: "), 
     actionButton("readFile","Read File"), 
     tags$hr() 
    ), 
     mainPanel(
     tableOutput('contents') 
    ))) 
), 
server = shinyServer(function(input,output,session){ 
    file <- reactiveValues(path=NULL,md5=NULL,rendered=FALSE) 

    # Read file once button is pressed 
    observeEvent(input$readFile,{ 
    if (!file.exists(input$path)){ 
     print("No such file") 
     return(NULL) 
    } 
    tryCatch({ 
     read.csv(input$path) 
     file$path <- input$path 
     file$md5 <- digest(file$path,algo="md5",file=TRUE) 
     file$rendered <- FALSE 
    }, 
    error = function(e) print(paste0('Error: ',e))) 
    }) 

    observe({ 
    invalidateLater(1000,session) 
    print('check') 

    if (is.null(file$path)) return(NULL) 

    f <- read.csv(file$path) 
    # Calculate ckeksum 
    md5 <- digest(file$path,algo="md5",file=TRUE) 

    # If no change in cheksum, do nothing 
    if (file$md5 == md5 && file$rendered == TRUE) return(NULL) 

    output$contents <- renderTable({ 

     print('render') 
     file$rendered <- TRUE 
     f 
    }) 
    }) 

})) 
+0

我試過你的例子,但我無法再對文件進行修改。而且我不確定如何在代碼中使用它。我幾乎是一個初學者。 – Damata

+0

它適用於我,所以我不知道這是怎麼回事。嘗試將失效時間更改爲5秒'invalidateLater(5000,session)'也許讀取文件阻止了它的打開。你能打開應用程序中的文件嗎? –

+0

現在它也適用於我。我會嘗試在我的代碼中使用它。 – Damata

1

如果我理解正確的問題,我說你需要reactiveFileReader功能。從function's reference page

描述:

給定一個文件路徑和讀功能,返回該文件的內容的反應性數據源 。

文件讀取器將輪詢文件的更改,一旦檢測到更改,UI將被動地更新。

使用gallery example爲指導,我更新了服務器功能,在您的示例以下:

server <- function(input, output) {                                                         
    fileReaderData <- reactiveFileReader(500,filePath="df.xlsx", readFunc=read_excel) 
    output$df1 <- renderDataTable({                                                            
    DT::datatable(fileReaderData(), escape = FALSE, rownames=FALSE,class = "cell-border",                                              
       options =list(bSort = FALSE, paging = FALSE, info = FALSE)                                                  
)                                                                    
    })                                                                   
} 

就這樣,我保存到「df.xlsx」任何變化傳播幾乎立即到UI 。