Reputation: 11762
Am I missing something in the functions?
I want to copy a folder with some files and another subfolder from one location to another. I tried to use file.copy(from, to, recursive=TRUE)
but it complains with an error message:
In file.copy("my_folder", "new_folder", :
'recursive' will be ignored as 'to' is not a single existing directory
The result is a file called new_folder
with no content.
Is there a way to copy the complete folder structure with R?
Upvotes: 28
Views: 25140
Reputation: 11762
Ok, I just figured out what the error means... read every word carefully!
I have to create the new directory in advance and now I can copy everything...
dir.create('new_folder')
file.copy("my_folder", "new_folder", recursive=TRUE)
This works as expected.
Upvotes: 30
Reputation: 2631
If you want to copy files that lie inside one folder so that they lie inside of a second folder e.g.
dir1/file1.txt
dir1/nested/file2.txt
to:
dir2/file1.txt
dir2/nested/file2.txt
Then this code works:
from <- "dir1"
to <- "dir2"
file.copy(list.files(from, full.names = TRUE),
to,
recursive = TRUE)
Avoid using recursive=TRUE
in the list.files()
command otherwise you lose the nesting.
file.copy(list.files(from, full.names = TRUE, recursive = TRUE),
to,
recursive = TRUE)
# incorrect
# dir2/file1.txt
# dir2/file2.txt
Other answers above didn't help with above scenario, eg:
file.copy(from, to, recursive=TRUE)
# incorrect - makes:
# dir2/dir1/file1.txt
# dir2/dir1/nested/file2.txt
file.copy('(...)/path_to_folder_Z', '(...)/folder_X')
# overwrites existing folder if in same parent directory
Upvotes: 12
Reputation: 2213
Here is another possibility :
create_Directory <- function(source_Directory = "C:/dir1",
target_Directory = "C:/dir2")
{
setwd(source_Directory)
list_Dirs <- list.dirs()
setwd(target_Directory)
bool_Dir_Exists <- dir.exists(list_Dirs)
dirs_To_Create <- list_Dirs[!bool_Dir_Exists]
for(dir in dirs_To_Create)
{
dir.create(dir)
}
}
copy_Content_From_One_Directory_To_Another <- function(source_Directory = "C:/dir1",
target_Directory = "C:/dir2")
{
#### Create the sub directories ####
create_Directory(source_Directory = source_Directory,
target_Directory = target_Directory)
#### Copy the files ####
setwd(source_Directory)
list_Files <- list.files(recursive = TRUE, full.names = TRUE)
list_Files <- gsub(pattern = paste0("(\\.)",.Platform$file.sep), replacement = "", list_Files)
file.copy(from = paste0(source_Directory, .Platform$file.sep
, list_Files),
to = paste0(target_Directory, .Platform$file.sep , list_Files))
}
copy_Content_From_One_Directory_To_Another()
Upvotes: -1
Reputation: 1052
I'd rather write an R function that copies the directory using the Terminal. Here's what I use, but note that I wrote it only for Linux and OSX thus far.
dir.copy <- function(from, to) {
os <- Sys.info()['sysname']
if (os == "Darwin" || os == "Linux") {
command <- sprintf("cp -R '%s' '%s'", from, to)
system(command, intern = TRUE)
}
}
Quick, easy, and works like a charm.
Upvotes: 2
Reputation: 647
I think R.utils::copyDirectory(oldDir, newDir)
is the solution to what you're asking. It doesn't require creating newDir
first, either.
Upvotes: 23
Reputation: 666
as @matifou says in the comments, the accepted answer by the questioneer himself is a bit confusing, because you end up with the copied folder inside a folder with the same name as the copied folder... to avoid this, do this instead:
case: you want to move folder_X to folder_Z.
# create empty folder Z inside folder X
dir.create('(...)/folder_X/folder_Z')
# copy the folder
file.copy('(...)/path_to_folder_Z', '(...)/folder_X')
so the second argument to file.copy shold be just folder_X, and not the newly created folder_Z inside folder_X.
Because if you do that, the folder structure will be like this, which is probably not what you want:
(...)/folder_X/folder_Z/folder_Z
(Maybe this will save somebody the 10 minutes or so it took me to figure out)
Upvotes: 15