从 saveRDS() 语句中自动写入 readRDS() 语句

Posted

技术标签:

【中文标题】从 saveRDS() 语句中自动写入 readRDS() 语句【英文标题】:Automatically write readRDS() statements from saveRDS() statements 【发布时间】:2014-08-26 16:35:24 【问题描述】:

我经常在处理大量数据后编写saveRDS() 语句,这促使我立即编写readRDS() 以备将来访问.RDS 文件以更快地加载到R 的可重复编码。下面概述了我从输入的saveRDS() 语句生成readRDS() 语句的手动过程。如何改进?如何在EMACS 和/或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")

【问题讨论】:

【参考方案1】:

我能想到的两种方法是使用宏或多个光标。

我经常创建在一行上工作的宏,宏的最后一个动作是向下移动到下一行,所以我可以快速重复它。

在这种情况下,在您复制并粘贴 saveRDS 块后,在第一行:开始录制宏并执行以下操作:

    转到行首 前进两个字 在光标后标记和剪切单词 删除逗号 转到行首 猛拉 插入“ 删除接下来的 4 个字符(保存) 下移 1 行。 停止录制宏

关键是要以一种能够普遍应用于具有给定格式的所有行的方式记录宏。通过使用 forward-wordforward-sexp 之类的东西而不是逐个字符地移动,确保文件名类似于“foo-bar baz”的行可以通过宏以及简单的文件名(例如“bar”)进行转换。

然后你可以使用 C-xe 来运行宏,在下一行,然后按 e 再次运行它下一行直到完成。您也使用前缀参数,因此如果您知道要将其应用于 10 行,那么您可以使用 C-u10C-xe

这里我将宏记录在第一行,稍等片刻,然后快速将其应用到下面的两行。

您可以使用 name-last-kbd-macroinsert-kbd-macro 将此宏保存在您的 init 中,并在以后的会话中像命令一样使用它。

多个光标

或者您可以使用多个光标,这将允许您执行与宏相同的操作,但同时在所有行上。

https://github.com/magnars/multiple-cursors.el

【讨论】:

【参考方案2】:

也许你可以使用这样的东西:

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)
  ))

这是一个例子。我只是写信给tempdir,但你会输入你真正想要的目录。此外,为了演示,我在对象名称(重读时)前面加上了“test_”。将prefix 设置为""(默认)以保留原始名称。

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"

要重现您的操作,可以这样使用:

saveRead(dems, meds, anti, path = "./_00_data_original")

【讨论】:

以上是关于从 saveRDS() 语句中自动写入 readRDS() 语句的主要内容,如果未能解决你的问题,请参考以下文章

saveRDS膨胀对象的大小

使用 saveRDS 保存模型但没有足够的内存来读取 RDS?

有很多列时使用 readr::read_csv() 导入数据时覆盖列类型

如何在不编写正则表达式的情况下从字符串中解析日期?

在 r 中使用 readr 读取文件时的大整数

readr - 不读取缺少标题的列