在我的r代码中说:
a<-some code
b<-some code
c<-some code
我希望以某种方式保存这段代码,以便我可以随时调用它。如何将整个块保存为blockOfCode
,以便我可以将其调用为宏?换句话说如下:
Z<-some code
a<-some code
b<-some code
c<-some code
Y<-some code
a<-some code
b<-some code
c<-some code
Z<-some code
可以改写为:
Z<-some code
blockOfCode
Y<-some code
blockOfCode
Z<-some code
答案 0 :(得分:3)
您要求的是一个宏(与函数形成对比,后者接受参数并返回值而不是修改当前环境中的变量)。 R没有真正的宏。 This 2001 R News article by Thomas Lumley开始:
R邮件列表上熟悉的问题来源 是新转换的R用户正在尝试编写 然后R. Bill Venables的SAS或Stata代码指出 对他们来说,R不是一种宏观语言,而且是轻柔的 解释说,他们的解决方案更容易解决 问题。在本文中,我将解释一个宏 是的,为什么R不是一种宏观语言,这很好 如何将它合二为一。
Lumley提供的代码被放入gtools::defmacro()
函数中,描述了更多here。这是一个例子:
library(gtools)
## defmacro() needs an argument, even if you don't use it
f <- defmacro(x,expr = {a <- a+1})
a <- 0
f() ## you do need the parentheses here
a <- a+1
a
的值现在为1.
expr
可以包含任意数量的代码,因此您可以执行多个表达式。
但请阅读Lumley的文章。
答案 1 :(得分:0)
您的blockOfCode
可以通过几种方式处理,但通常需要您了解环境。
如果您在全球环境中执行所有操作,则以下操作将起作用。
a <- b <- c <- NA
blockOfCode <- function() {
a <<- 1
b <<- 2
c <<- 3
}
Z <- 11
blockOfCode()
Y <- 22
blockOfCode()
Z <- 33
如果本地环境(功能环境)中没有变量,深度分配箭头<<-
将分配给全局环境。第一行a <- b <- c <- NA
是必要的,因为如果您在没有首先创建变量c
的情况下使用深度赋值,则会产生错误,可能是因为c()
用于创建向量。通常我会尽量避免使用c
作为变量。
此外,通常不鼓励深度分配,因为它可能会导致一些不可预测的结果。
您可以改为使用assign
并指定环境。在这种情况下,使用parent.frame
会将您从功能环境转移到全局环境。
blockOfCode <- function() {
assign("a", 1, envir = parent.frame())
assign("b", 2, envir = parent.frame())
assign("c", 3, envir = parent.frame())
}
Z <- 11
blockOfCode()
Y <- 22
blockOfCode()
Z <- 33
这样做的好处是不需要提前创建a,b和c变量。您还可以指定另一个环境而不是全局环境。
所有这一切,你的例子可能太简单,无法说明你想要做什么。没有理由不止一次运行blockOfCode
,因为a,b和c的值不会发生变化。在您更复杂的现实世界中,可能需要修改上述内容。
答案 2 :(得分:0)
以下是一些可能性:
1)eval / substitute 将代码块放在R函数中,但在编写函数时,将eval.parent(substitute({
放在开头,将}))
放在最后,然后只放在适当的点运行该功能。没有包使用。
block <- function() eval.parent(substitute({
a <- 1
b <- 2
c <- 3
}))
Z <- 1
block()
cat("Z:", Z, "a:", a, "b:", b, "c:", c, "\n")
## Z: 1 a: 1 b: 2 c: 3
rm(a, b, c)
Z <- 2
block()
cat("Z:", Z, "a:", a, "b:", b, "c:", c, "\n")
## Z: 2 a: 1 b: 2 c: 3
2)附加通常最好避免将环境附加到搜索路径,因为它可能会导致一些意外行为,但它确实提供了另一种可能的解决方案。定义block2
函数以返回environment()
,然后附加运行函数的结果。请注意,这不会将a
,b
和c
放入全局环境中,而是将它们附加到位于搜索路径上的单独环境block2()
中。可以使用ls("block2()")
列出该环境的内容,并使用detach("block2()")
删除该环境。没有包使用。
block2 <- function() {
a <- 1
b <- 2
c <- 3
environment()
}
Z <- 1
attach(block2())
search() # note new 2nd element on search path
## [1] ".GlobalEnv" "block2()" "package:stats"
## [4] "package:graphics" "package:grDevices" "package:utils"
## [7] "package:datasets" "package:methods" "Autoloads"
## [10] "package:base"
ls("block2()")
## [1] "a" "b" "c"
cat("Z:", Z, "a:", a, "b:", b, "c:", c, "\n")
## Z: 1 a: 1 b: 2 c: 3
detach("block2()")
Z <- 2
attach(block2())
cat("Z:", Z, "a:", a, "b:", b, "c:", c, "\n")
## Z: 2 a: 1 b: 2 c: 3
3)quote / eval 将块的语句放入quote({...})
,然后在运行时eval
。没有包使用。
block3 <- quote({
a <- 1
b <- 2
c <- 3
})
Z <- 1
eval(block3)
cat("Z:", Z, "a:", a, "b:", b, "c:", c, "\n")
## Z: 1 a: 1 b: 2 c: 3
rm(a, b, c)
Z <- 2
eval(block3)
cat("Z:", Z, "a:", a, "b:", b, "c:", c, "\n")
## Z: 2 a: 1 b: 2 c: 3