【问题标题】:Is there a way to load several excel files from a dropbox folder into an R-shiny app?有没有办法将几个 excel 文件从 Dropbox 文件夹加载到 R-shiny 应用程序中?
【发布时间】:2020-05-20 13:10:53
【问题描述】:

我在 R Shiny 中工作还是比较新的,我正在尝试将几个 excel 文件加载到 R-shiny 应用程序中。部分问题是我需要能够从保管箱文件夹中提取多个文件,而无需指定数据文件的名称。所以我需要能够告诉 R 从 Dropbox 文件夹中读取所有文件。我正在使用的文件也是 .xlsx 格式,我需要将它们读入 R 中。

我首先尝试使用计算机桌面上的文件夹来执行此操作。我设法使用我的本地目录和下面的代码让它工作:

library(readxl)
library(tidyverse)

files <- list.files(path = "~/Desktop/data", pattern = "*.xlsx", full.names = TRUE) #read files from folder on desktop
df <- sapply(files, read_excel, simplify = FALSE) %>% #read files from the path, and bind them together
  bind_rows() 

我尝试调整上面的代码以使用 rdrop2 中的 drop_dir 函数。我试过的代码如下:

library(rdrop2)
library(tidyverse)
library(readxl)

token <- drop_auth()
files <- drop_dir("!dropbox_folder", dtoken = token) #List all files in Dropbox folder MPD_03_Test
f <- files$path_display #list directory to dropbox
df <- sapply(f, read_excel, simplify = FALSE) %>%  #runs the read function for all the files that are pulled
  bind_rows() # .id="id creates a unique ID for each row and then binds them all together based on the ID.

当我运行它时,代码不会将数据文件从保管箱加载到 R 中。当我运行保管箱代码时,它只会创建一个空对象。任何关于去哪里解决这个问题的帮助将不胜感激!此外,如果这有助于构建您可能对如何解决我的问题提出的任何建议,我打算将其用作我将数据读入和 R-shiny 应用程序的方式。

谢谢!

【问题讨论】:

  • Dropbox 文件夹中的文件实际上可能并不位于本地,而只是呈现在文件资源管理器中(有点像占位符)。只有打开时才会下载文件。我不确定这与 R 的关系如何。您需要解决的问题是:files 中是否列出了任何文件?当您在单个文件上使用read_excel 时会发生什么?在尚未下载的单个文件上?

标签: r shiny


【解决方案1】:

@MrGumble 在他的 cmets 中是正确的。这些文件需要在阅读之前下载。 drop_dir() 函数列出了保管箱服务器上的文件路径,我们只能读取本地保存到我们机器的数据。如果您有 .csv 文件,则可以使用 drop_read_csv() 函数一步完成。但是由于您有 excel 文件,因此需要首先使用drop_download() 显式下载这些文件,然后使用read_excel() 读取。

library(rdrop2)
library(tidyverse)
library(readxl)
#install.packages("xlsx")
library(xlsx)

token <- drop_auth()

#make a few excel file with iris dataset, save locally, and upload to dropbox root
iris_filenames <- paste0("iris", 1:3, ".xlsx")
walk(iris_filenames, ~write.xlsx(iris, file = .x, row.names = FALSE))
walk(iris_filenames, drop_upload)

#list all files on dropbox root and filter for only iris ones
iris_files_on_dropbox <- drop_dir(dtoken = token) %>% 
  filter(str_detect(name, 'iris'))
#make new filenames so we can see that the download worked correctly
#you could do overwrite = TRUE and not pass through new filenames
#see ?drop_download for all options
new_iris_filenames <- paste0("iris", 1:3, "-from-dropbox.xlsx")

#download the files first
walk2(iris_files_on_dropbox$name, new_iris_filenames, ~drop_download(path = .x, local_path = .y))

#then read them all in
df <- bind_rows(map(new_iris_filenames, read_xlsx))

此外,我们可以创建自己的自定义函数来完成下载和读取,就像drop_read_csv() 通过更改此函数的源代码所做的那样。我们需要做的就是将read...() 函数从read.csv 更改为read_excel,并将dtoken 默认get_drop_token() 的引用更改为rdrop2:::get_drop_token(),这是rdrop2 包中未导出的函数,因此我们需要三个': ::'。

#source for drop_read_csv we can rewrite for excel files
# drop_read_csv <- function(file, dest = tempdir(), dtoken = get_dropbox_token(), ...) {
#   localfile = paste0(dest, "/", basename(file))
#   drop_download(file, localfile, overwrite = TRUE, dtoken = dtoken)
#   utils::read.csv(localfile, ...)
# }


drop_read_excel <- function(file, dest = tempdir(), dtoken = rdrop2:::get_dropbox_token(), ...) {
  localfile = paste0(dest, "/", basename(file))
  drop_download(file, localfile, overwrite = TRUE, dtoken = dtoken)
  readxl::read_excel(localfile, ...)
}

df2 <- bind_rows(map(iris_files_on_dropbox$name, drop_read_excel))

要在闪亮的应用程序中工作,我们首先需要保存drop_auth 令牌,以便我们可以在使用闪亮的应用程序时进行身份验证。将其保存到闪亮的应用目录中。

saveRDS(token, file = "token.rds")

现在这是一个闪亮的应用程序。单击“开始”按钮时,将下载 iris excel 文件并显示在 UI 中。我们需要在全局环境或 global.R 中调用 drop_auth() 以及自定义的 drop_read_excel() 函数才能使用它。

library(shiny)
library(rdrop2)
library(tidyverse)


#saveRDS(token, file = "token.rds") into shiny app directory
#authenticate in global.R or outside of ui/server 
drop_auth(rdstoken = "token.rds")
drop_read_excel <- function(file, dest = tempdir(), dtoken = rdrop2:::get_dropbox_token(), ...) {
  localfile = paste0(dest, "/", basename(file))
  drop_download(file, localfile, overwrite = TRUE, dtoken = dtoken)
  readxl::read_excel(localfile, ...)
}


ui <- fluidPage(
  actionButton("go", "go"),
  tableOutput("table")

)

server <- function(input, output, session) {
 df <-  eventReactive(input$go, {
   withProgress(message = 'Downloading from dropbox',
                detail = 'This may take a while...', value = 0.5, {
    iris_files_on_dropbox <- drop_dir() %>% 
      filter(str_detect(name, 'iris'))
    setProgress(value = 0.75)
    df <- bind_rows(map(iris_files_on_dropbox$name, drop_read_excel))
    setProgress(value = 1)
                })
   return(df)
  })

 output$table <- renderTable({
   df()
 })

}

shinyApp(ui, server)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-18
    • 2022-11-19
    • 1970-01-01
    • 2022-10-18
    • 1970-01-01
    • 2020-07-31
    • 2021-08-02
    • 2019-11-21
    相关资源
    最近更新 更多