我正在创建一个R包,在这里我想存储我在过去写过的几个函数。由于我知道无论何时调用外部函数,我都应该使用双冒号操作符package::function
,因此我正在使用RStudio中的代码来修复所有函数调用。
是否有一种方式来编写脚本/使其自动化?它看起来像是一些不应该手动完成的事情,但是我在任何地方都找不到这样做的方法。
PS:我知道我也可以直接或通过@importFrom package function
将NAMESPACE
添加到NAMESPACE
中,但是这也涉及到大量的手工输入,以及大量从函数主体到头部的来回输入。
发布于 2022-10-21 08:18:02
基本上,您想要的是找到模式并在其前缀加上一些内容,其中gsub
是您的朋友。
认为下面是一种方法的草图!
您可能有一个名称列表,其中包含外部包的名称和函数,如下所示。
funs_p1 <- c('exfun1a', 'exfun1b')
funs_p2 <- c('exfun2')
funs_p3 <- c('exfun3')
(fun_lst <- list(pac1=funs_p1, pac2=funs_p2, pac3=funs_p3))
# $pac1
# [1] "exfun1a" "exfun1b"
#
# $pac2
# [1] "exfun2"
#
# $pac3
# [1] "exfun3"
你的工作目录里最好的cd,
setwd('fundir')
并使用.R列出list.files
脚本。
rscripts <- list.files(pattern='.R$')
然后在循环中使用lapply
遍历R脚本的文件名,
readLines
到带有函数名的objectgsub
模式中,并在它们的前缀加上包名和for
loopwriteLines
中的冒号到.R脚本(我用'changed_'
作为前缀,应该很容易移除,但不会覆盖原始文件,如果确定的话,请注释掉行,否则只会写文本)
lapply(rscripts, \(x) {
rl <- readLines(x)
for (i in seq_along(fun_lst)) {
rl <- gsub(sprintf('(%s)', paste(paste0(fun_lst[[i]], '\\('), collapse='|')),
sprintf('%s::\\1', names(fun_lst)[i]), rl)
}
# writeLines(rl, paste0('changed_', x)) |> invisible()
return(rl)
})
# [[1]]
# [1] "myfun1a <- function() {"
# [2] " a <- pac1::exfun1a(some, args)"
# [3] " mean(a)"
# [4] "}"
# [5] ""
# [6] "myfun1b <- function() {"
# [7] " a <- pac3::exfun3(some, args)"
# [8] " sum(a)"
# [9] "}"
#
# [[2]]
# [1] "myfun2 <- function() {"
# [2] " a <- pac1::exfun1b(some, args)"
# [3] " mean(a)"
# [4] "}"
#
# [[3]]
# [1] "myfun3 <- function() {"
# [2] " a <- pac2::exfun2(some, args)"
# [3] " sum(a)"
# [4] "}"
注意,这是危险的,并且可能会覆盖您的工作而不撤消!因此,请确保创建一个备份副本,并使用这个玩具示例进行练习。
警告:在整个包中都有同名的函数,例如stats::filter
和dplyr::filter
,您应该排除它们以避免产生混乱。另外,如果对象具有相同的名称或部分,它们可能也会加上前缀,我试图通过在模式中添加括号来实现这一点。
数据:
将这些行存储在三个单独的.R脚本中以复制:
# fun1.R:
myfun1a <- function() {
a <- exfun1a(some, args)
mean(a)
}
myfun1b <- function() {
a <- exfun3(some, args)
sum(a)
}
# fun2.R:
myfun2 <- function() {
a <- exfun1b(some, args)
mean(a)
}
# fun3.R:
myfun3 <- function() {
a <- exfun2(some, args)
sum(a)
}
https://stackoverflow.com/questions/74154109
复制相似问题