1

I deployed passive acoustic recorders to detect animal calls but on one of my devices the date & time settings got messed up and reverted to the default (Jan 1, 2000). And then the device recorded for a month, writing 20-min files that are day & time stamped. e.g., file name is swift1_20000101_020000.wav (deviceName_YYYYMMDD_HHMMSS). And now I reeeeally don't want to have to manually rename 2000+ individual files.

I know the actual start date & time from my field notes and I'm wondering if there's a way to input that actual start date/time and have all the files shift off of that. So swift1_20000101_000000 would become swift1_20220617_093000, swift1_20000101_002000 would become swift1_20220617_095000, and so on in some sort of loop.

Any ideas? I know you can rename files with file.rename(), paste0(), etc but I would need a function that iterated on all files within the directory sequentially and I haven't been able to find something that will do it. Any thoughts or ideas would be much appreciated!

3
  • Selene Fregosi told me to post it here Jun 28 at 13:38
  • 4
    @Thejasvi While you could argue that this question is better suited for a different platform, I think this is a very common problem in bioacoustic data logging and if this site is going to be the leader for bioacoustic-related questions, I would argue that it is an appropriate question to ask here. Jun 28 at 15:09
  • 1
    Have deleted my comments seeing the discussion at the Meta play out! There is indeed sense in having field-specidic programming questions.
    – Thejasvi
    Jun 30 at 8:03

1 Answer 1

10

This is a common problem and we run into it often. I have mocked up some example R code to show how you can handle this problem in R as described. You can also build a new folder structure and use this (or similar) code to reorganize files.

library(stringr)
library(lubridate)
library(fs)
library(dplyr)

# set deployment date/time
datetime_deployment= ymd_hms("20220617_093000")

# list all the files that need to be changed
# files<-dir_ls("path/to/files",glob = "*wav")

files<-c("path/to/file/swift1_20000101_020000.wav",
         "path/to/file/swift1_20000101_022000.wav")

# We will use this data frame for organizing the new paths to which 
# we will rename your files
dat<-data.frame(path=files,
                filename=basename(files)) %>%
    mutate(
        # extract the file datetimes
        datetime=ymd_hms(str_extract(filename,"[0-9]{8}_[0-9]{6}")),
        # find the difference between your files and the deployment datetime
        diff=datetime_deployment-datetime,
        # add the max of the differences to the file date time (this
        # assumes that the deployment datetime is after all
        # of the file datetimes)
        datetime_new=datetime+max(diff),
        # extract the sensor_name from the filename (for your usecase
        # this regex is way overkill but it works for other
        # prefixes and datetime formats)
        sensor_name=str_extract(filename,
             '^.*?(?=((_D[0-9]{8}(\\([0-9]\\)|_))?(_|-)?D?[0-9]{8}(T|_)[0-9]{6}))'),
        # get the file extention (useful if you have more than 1)
        file_ext=path_ext(path),
        # build new path
        new_path=file.path(dirname(path),
                           paste0(sensor_name,"_",
                                  format(datetime_new, 
                                         "%Y%m%d_%H%M%S"),".", 
                                         file_ext)))

# check for duplicates and fix if there are, otherwise you will
# overwrite them when you move
dat %>% 
    group_by(new_path) %>%
    tally %>% 
    filter(n>1)

# you can copy the files (will not change the originals) or you can
# move the files (the originals disappear).  Use copy=TRUE
# if you are unsure if you have the correct paths and want to be able
# to go back to the originals
copy = TRUE


if(copy==TRUE){
    # slow and you will get a copy of the file (but it is safe if you
    # have any mistakes in the new path you will still have
    # the old data)
    file_copy(dat$path,dat$new_path, overwrite = F)
}else{
    # WAY faster but distructive (essentially will rename the files)
    file_move(dat$path,dat$new_path)
}
2
  • Awesome, thank you so much!! Will give this go and report back... Jun 28 at 13:37
  • @CarlyBatist did this code work to solve your problem? Jul 5 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.