为什么<<-分配在我的函数中起作用,但是<-却不起作用?

时间:2018-07-05 12:14:04

标签: r assignment-operator

我试图了解实践中<-<<-之间的区别。我在R中编写了以下函数,该函数依赖于我编写的其他几个小函数:

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

函数prompt1prompt2接受用户输入,el.type()为数据分配字符串名称(用于自动描述不同的图),data.sift()提取相关信息来自大数据框架对象的数据,evol.tiles()生成各种ggplots,将其组织在网格中,evol.plot()将图放置在网格中。

可以看出,data.sift()evol.tiles()函数都使用id2用户的输入。按原样执行此功能时,出现错误:

Error in evol.tiles(ds = dat.sifted, dt = el.type, nc = id2) : object 
'id2' not found 

如果我将id2 <- prompt2()替换为id2 <<- prompt2(),则代码将按预期工作。

我不明白的是,为什么代码不会在data.sift()函数上中断,该函数也需要id2。我阅读了help的作业,StackOverflow上的一些相关帖子以及ScopeAn Introduction to R部分,但我仍然不确定问题出在哪里。好像在data.sift()中使用该变量之后,该变量在环境中不再可用,我不知道这一点。

任何帮助将不胜感激。

更新: 这是提示代码:

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

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

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 个答案:

答案 0 :(得分:0)

如评论中所述,我认为我找到了问题-在研究一个最小的工作示例时,我发现在函数evol.tiles()中我正在调用id2变量而不是{{1} }(在内循环中)。我猜想当我将nc用于<<-时,我在全局分配了它,然后可以在prompt2()中调用它时找到它,但是对于evol.tiles()来说,{{ 1}}。

即使如此,我还是不太明白为什么会这样。我认为该函数应该在父母环境中查找缺少的参数,并且由于<-是在evol.tiles()中定义的,因此id2应该能够找到正确的值。

这是一个简单的示例,显示了即使代码名不正确,我仍希望代码表现如何:

fun.exec()

如果我自己运行time.evol()函数,则会收到与函数相同的错误,这正是我所期望的。但是,如果我为test <- function(){x*x} test() Error in test() : object 'x' not found 赋值,即

test()

该功能正常工作。有人可以告诉我为什么我的功能没有以同样的方式运行吗?

更新: @Aaron:您提供的示例x对我来说很好执行:

enter image description here

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