drmariod
drmariod

Reputation: 11762

Copy folder recursive in R

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

Answers (6)

drmariod
drmariod

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

MarkeD
MarkeD

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

Emmanuel Hamel
Emmanuel Hamel

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

Christian
Christian

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

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

emilBeBri
emilBeBri

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

Related Questions