This question already has an answer here:
这个问题在这里已有答案:
- Nested function environment selection 2 answers
- 嵌套功能环境选择2个答案
I am trying to understand the difference between <-
and <<-
in practice. I wrote the following function in R
that relies on a couple of other small function that I wrote:
我试图在实践中理解< - 和< <之间的区别。我在r中编写了以下函数,它依赖于我写的其他一些小函数:< p>
fun.exec <- function(x=dat){
id1 <- prompt1()
id2 <- prompt2()
el.type <- data.switch(di=id1)
dat.sifted <- data.sift(x, nc=id2)
plots.list <- evol.tiles(ds=dat.sifted, dt=el.type, nc=id2)
p <- evol.plot(l=plots.list, dt=el.type)
}
Functions prompt1
and prompt2
take an input from a user, el.type()
assigns string name to the data (for use in describing different plots automatically), data.sift()
extract relevant data from a big data frame object, evol.tiles()
generates various ggplots to be organized in a grid, and evol.plot()
puts the plots in a grid.
函数prompt1和prompt2从用户获取输入,el.type()为数据分配字符串名称(用于自动描述不同的图),data.sift()从大数据框对象中提取相关数据,evol.tiles ()生成要在网格中组织的各种ggplots,evol.plot()将绘图放在网格中。
As can be seen, both data.sift()
and evol.tiles()
functions use the id2
user's input. When I execute this function as is, I get an error:
可以看出,data.sift()和evol.tiles()函数都使用id2用户的输入。当我按原样执行此函数时,出现错误:
Error in evol.tiles(ds = dat.sifted, dt = el.type, nc = id2) : object
'id2' not found
If I replace id2 <- prompt2()
with id2 <<- prompt2()
, the code works as expected.
如果我用id2 << - prompt2()替换id2 < - prompt2(),代码按预期工作。
What I don't understand is why, as is, the code does not break on the data.sift()
function, which also calls for id2
. I read help for assignments, a couple of related posts on *, and the Scope section from An Introduction to R but I am still not sure what the problem is. It's almost as if after being used in data.sift()
the variable was no longer available in the environment and I don't understand that is.
我不明白的原因是,为什么代码不会破坏data.sift()函数,它也会调用id2。我阅读了有关作业的帮助,*上的几个相关帖子以及R简介中的Scope部分,但我仍然不确定问题是什么。这几乎就像在data.sift()中使用后,变量在环境中不再可用,我不明白。
Any help will be greatly appreciated.
任何帮助将不胜感激。
UPDATE: Here is the code for prompts:
更新:这是提示的代码:
prompt1 <- function(){
cat('What do you want to create plots for? Your options are:
1: data type A,
2: data type B,
3: data type C')
readline(prompt="Enter an integer: ")
}
prompt2 <- function(){
cat('How many nodes do you want to visualize?')
n <- readline(prompt="Enter an integer: ")
cat('\nProvide coordinates of each node to visualize separated by commas.')
l <- vector("list", n)
for (i in 1:n){
el <- readline(prompt=paste('Enter coordinnates for node',i,': '))
l[[i]] <- el
}
return(l)
}
for data.sift()
:
for data.sift():
data.sift <- function(x, nc){
nl <- lapply(nc, function(l){as.integer(unlist(strsplit(l,",")))})
ds <- vector("list", length(nl))
for (i in 1:length(nl)){
ds[[i]] <- x[(x$x == nl[[i]][1] & x$y == nl[[i]][2] & x$z == nl[[i]][3]),]
}
return(ds)
}
and for evol.tiles()
:
并为evol.tiles():
evol.tiles <- function(ds, dt, nc){
require(ggplot2)
my.cols <- rainbow(length(ds))
my.names <- as.character(nc)
names(my.cols) <- my.names
my.list <- list()
for (i in 1:6){
for (ii in 1:length(id2)){
p <- ggplot(NULL, aes_(x = as.name(names(ds[[ii]][4]))))
p <- p + geom_line(data = ds[[ii]],
aes_(y = as.name(names(ds[[ii]][i])),
colour = as.character(nc[[ii]])))
}
p <- p + scale_colour_manual("Node",
breaks = as.character(nc),
values = my.cols)
my.list[[i-dr[1]+1]] <- p
}
return(my.list)
}
1 个解决方案
#1
0
As posted in the comments, I think I found the issue - while working on a minimal working example I discovered that in my function evol.tiles()
I was calling the id2
variable instead of nc
(in the inner loop). I guess when I used <<-
for prompt2()
I was assigned it globally and then it could be found when called from within evol.tiles()
but with <-
it was not available to evol.tiles()
.
正如在评论中发表的那样,我认为我发现了这个问题 - 在处理一个最小的工作示例时,我发现在我的函数evol.tiles()中我调用了id2变量而不是nc(在内部循环中)。我想当我使用<< - for prompt2()时,我被全局分配,然后在evol.tiles()中调用时可以找到它,但是< - 它不能用于evol.tiles()。
Even so, I still don't quite understand why was that happening. I would think that that the function should look in the parenting environment for the missing arguments and since the id2
was defined within fun.exec()
, the time.evol()
should be able to find the right value.
即便如此,我仍然不太明白为什么会这样。我认为该函数应该在父级环境中查找缺少的参数,并且因为id2是在fun.exec()中定义的,所以time.evol()应该能够找到正确的值。
Here is a simple example showing how I would expect the code to behave, even with an incorrectly named variable as it was in my case:
下面是一个简单的示例,显示了我希望代码的行为方式,即使在我的情况下使用了错误命名的变量:
test <- function(){x*x}
test()
Error in test() : object 'x' not found
If I run the test()
function on its own, I get the same error as with my function, whic is what I would expect. However, if I assign value to x
, i.e.,
如果我自己运行test()函数,我会得到与我的函数相同的错误,这正是我所期望的。但是,如果我为x赋值,即
x <- 2
test()
[1] 4
the function works just fine. Could someone tell me why wasn't my function behaving in the same way?
功能工作得很好。有人能告诉我为什么我的功能不是以同样的方式表现吗?
UPDATE: @Aaron: The example you gave, i.e., rm(x); test2 <- function() { x <- 2; test() }; test2()
, executes for me just fine:
更新:@Aaron:你给出的例子,即rm(x); test2 < - function(){x < - 2; test()}; test2(),对我执行就好了:
So I still don't understand what the issue is. Any thoughts?
所以我仍然不明白这是什么问题。有什么想法吗?
#1
0
As posted in the comments, I think I found the issue - while working on a minimal working example I discovered that in my function evol.tiles()
I was calling the id2
variable instead of nc
(in the inner loop). I guess when I used <<-
for prompt2()
I was assigned it globally and then it could be found when called from within evol.tiles()
but with <-
it was not available to evol.tiles()
.
正如在评论中发表的那样,我认为我发现了这个问题 - 在处理一个最小的工作示例时,我发现在我的函数evol.tiles()中我调用了id2变量而不是nc(在内部循环中)。我想当我使用<< - for prompt2()时,我被全局分配,然后在evol.tiles()中调用时可以找到它,但是< - 它不能用于evol.tiles()。
Even so, I still don't quite understand why was that happening. I would think that that the function should look in the parenting environment for the missing arguments and since the id2
was defined within fun.exec()
, the time.evol()
should be able to find the right value.
即便如此,我仍然不太明白为什么会这样。我认为该函数应该在父级环境中查找缺少的参数,并且因为id2是在fun.exec()中定义的,所以time.evol()应该能够找到正确的值。
Here is a simple example showing how I would expect the code to behave, even with an incorrectly named variable as it was in my case:
下面是一个简单的示例,显示了我希望代码的行为方式,即使在我的情况下使用了错误命名的变量:
test <- function(){x*x}
test()
Error in test() : object 'x' not found
If I run the test()
function on its own, I get the same error as with my function, whic is what I would expect. However, if I assign value to x
, i.e.,
如果我自己运行test()函数,我会得到与我的函数相同的错误,这正是我所期望的。但是,如果我为x赋值,即
x <- 2
test()
[1] 4
the function works just fine. Could someone tell me why wasn't my function behaving in the same way?
功能工作得很好。有人能告诉我为什么我的功能不是以同样的方式表现吗?
UPDATE: @Aaron: The example you gave, i.e., rm(x); test2 <- function() { x <- 2; test() }; test2()
, executes for me just fine:
更新:@Aaron:你给出的例子,即rm(x); test2 < - function(){x < - 2; test()}; test2(),对我执行就好了:
So I still don't understand what the issue is. Any thoughts?
所以我仍然不明白这是什么问题。有什么想法吗?