有一些先前的相关问题(1、2、3 ),但没有什么是我想要的,而且我无法让Jenny Bryan 在 2018 年发布的代码示例正常工作。
我有一个与我共享的文件夹,其中包含一些大文件。文件是嵌套的。所以我想递归到子目录并获取每个子目录中的所有文件。就我而言,只有两层,但如果有一种适用于任意数量层的方法就更好了。
最明显的尝试命令就是告诉它下载文件夹,希望它能找出子结构:
#load the libraries
library(tidyverse)
library(googledrive)
#folder link to id
#hidden for privacy reasons
jp_folder = "https://drive.google.com/drive/folders/XXXXX"
folder_id = drive_get(as_id(jp_folder))
#download in entirety
drive_download(folder_id)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用,因为它显然无法处理文件夹:
> drive_download(folder_id)
Error: Not a recognized Google MIME type:
* application/vnd.google-apps.folder
Run Code Online (Sandbox Code Playgroud)
我尝试通过进入每个子目录来避免此问题:
#load the libraries
library(tidyverse)
library(googledrive)
#folder link to id
#hidden for privacy reasons
jp_folder = "https://drive.google.com/drive/folders/XXXXX"
#get the id data frame
folder_id = drive_get(as_id(jp_folder))
#find files in folder
files = drive_ls(folder_id)
#loop dirs and download files inside them
for (i in seq_along(files$name)) {
i_dir = drive_ls(files$id[i])
#download files
walk(i_dir$id, ~ drive_download(as_id(.x)))
}
Run Code Online (Sandbox Code Playgroud)
该files对象看起来不错(用填充物替换字符串):
# A tibble: 6 x 3
name id drive_resource
* <chr> <chr> <list>
1 A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA <named list [32]>
2 B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB <named list [32]>
3 C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC <named list [31]>
4 D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD <named list [31]>
5 E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE <named list [31]>
6 F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF <named list [31]>
Run Code Online (Sandbox Code Playgroud)
但是,当尝试获取子目录的内容时,会抛出以下错误:
> i_dir = drive_ls(files$id[i])
Error: 'path' does not identify at least one Drive file.
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?
其实很简单:drive_ls()想要一个包含 1 行的数据框输入,而不是字符向量。该错误消息具有误导性(如果它只是告诉用户给它一个数据框,那就太好了)。如果将代码更改为该代码,并添加所需的循环,则可以自动下载子目录的内容。如果有子子目录,它将失败。需要在包中编写和实现适当的递归函数。
这段代码对我有用:
#load the libraries
library(stringr)
library(googledrive)
#folder link to id
jp_folder = "https://drive.google.com/drive/folders/XXXXX"
folder_id = drive_get(as_id(jp_folder))
#find files in folder
files = drive_ls(folder_id)
#loop dirs and download files inside them
for (i in seq_along(files$name)) {
#list files
i_dir = drive_ls(files[i, ])
#mkdir
dir.create(files$name[i])
#download files
for (file_i in seq_along(i_dir$name)) {
#fails if already exists
try({
drive_download(
as_id(i_dir$id[file_i]),
path = str_c(files$name[i], "/", i_dir$name[file_i])
)
})
}
}
Run Code Online (Sandbox Code Playgroud)
此版本会跳过已下载的文件。