为什么

时间:2022-04-20 13:28:08

This question already has an answer here:

这个问题在这里已有答案:

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?

所以我仍然不明白这是什么问题。有什么想法吗?