Reputation: 2738
I often write saveRDS()
statements after a good deal of data munging and this prompts me to immediately write readRDS()
for future, reproducible coding accessing the .RDS files for faster loading into R
. My manual process for generating readRDS()
statements from the typed saveRDS()
statements is outlined below. How can it be improved? How can I write a macro/function to do this for me, in EMACS
and/or R
?
## I type these out:
saveRDS(dems,"./_00_data_original/dems.RDS")
saveRDS(meds,"./_00_data_original/meds.RDS")
saveRDS(anti,"./_00_data_original/anti.RDS")
## Then I rectangle kill (C-x-r-k) the file names and commas
## and rectangle yank (C-x-r-y) them on the left hand side
## note: depends on filenames being equal lengths
dems,saveRDS("./_00_data_original/dems.RDS")
meds,saveRDS("./_00_data_original/meds.RDS")
anti,saveRDS("./_00_data_original/anti.RDS")
## then I Esc-Shift-5 to query replace ",saveRDS" with " <- readRDS"
dems <- readRDS("./_00_data_original/dems.RDS")
meds <- readRDS("./_00_data_original/meds.RDS")
anti <- readRDS("./_00_data_original/anti.RDS")
Upvotes: 4
Views: 1102
Reputation: 193527
Perhaps you can use something like this:
saveRead <- function(..., path, prefix = "", envir = .GlobalEnv) {
dots <- substitute(list(...))[-1]
objs <- sapply(dots, deparse)
new_objs <- paste0(prefix, objs)
paths <- file.path(path, paste0(objs, ".RDS"))
invisible(lapply(seq_along(objs), function(x) {
saveRDS(get(objs[x], envir = envir), file = paths[x])
assign(new_objs[x], readRDS(paths[x]), envir = envir)
}))
}
Here's an example. I'm just writing to a tempdir
, but you would enter your actual desired directory. Also, for the sake of demonstration, I've prefixed the object name (on re-read) with "test_". Set prefix
to ""
(default) to keep the original name.
a <- 1:2
b <- 3:4
ls()
# [1] "a" "b" "saveRead"
x <- tempdir()
list.files(x, ".RDS")
# character(0)
saveRead(a, b, path = x, prepend = "test_")
ls()
# [1] "a" "b" "saveRead" "test_a" "test_b" "x"
list.files(x, ".RDS")
# [1] "a.RDS" "b.RDS"
To reproduce your actions, it could be used like:
saveRead(dems, meds, anti, path = "./_00_data_original")
Upvotes: 2
Reputation: 4029
Two ways I can think of are using a macro or multiple cursors.
I often create macros that work on a single line, and the last action of the macro is to move down to the next line, so I can repeat it quickly.
In this case after you copied and pasted the saveRDS blocks, on the first line: begin recording a macro and perform these actions:
The key is to record the macro in a way that it will be able to apply genericaly to all lines with the given format. Making sure lines where the filename is something like "foo-bar baz" can be transformed by the macro as well as simple filenames like "bar" by using things like forward-word
or forward-sexp
instead of moving character by character.
Then you can use C-xe to run the macro, on the next line, and just press e to run it again on the next lines until done. You use a prefix argument too, so if you know you want to apply it to 10 lines, then you can use C-u10C-xe
Here I record the macro on the first line, wait a second, then quickly apply it to both lines below.
You can save this macro in your init by using name-last-kbd-macro
and insert-kbd-macro
and use it like a command in future sessions.
Or you can use multiple cursors, this will allow you to perform the same action as the macro, but on all the lines at the same time.
https://github.com/magnars/multiple-cursors.el
Upvotes: 4