2017-06-13 56 views
1

这看起来应该很简单。我以为我会做一个小时间表功能,以便我可以跟踪工作中的时间。以下是代码:数据帧不随rbind变化

timesheet <- data.frame(matrix(nrow = 0, ncol = 3)) 
varn <- c("date", "project", "status") 
colnames(timesheet) <- varn 

timesheet[1,] <- c(date(), "test", "test") 
#The above line exists because rbind was renaming the columns otherwise 

new.task <- function(project){ 
    timesheet <- append(time, c(date(), project, "started")) 
} 

new.task("Name of task") 

但是,数据帧保持不变而不会引发错误。这里发生了什么?

回答

1

原因在于作为R词法作用域和“环境”的概念作为存储空间:

“时间表”的对象是在全球环境声明。然而,你的代码试图附加的“时间表”对象在“new.task”函数的范围内声明。所以“append”命令只是追加到本地的“时间表”中,而不是全局的。

为了说明划定范围和环境下,我加入了一些提示性行代码:

library(pryr) 

timesheet <- data.frame(matrix(nrow = 0, ncol = 3)) 
varn <- c("date", "project", "status") 
colnames(timesheet) <- varn 

timesheet[1,] <- c(date(), "test", "test") 
#The above line exists because rbind was renaming the columns otherwise 

print(environment()) 
print(ls(environment())) 
sprintf("address of timesheet object is %s", pryr::address(timesheet)) 

new.task <- function(project){ 
    timesheet <- append(time, c(date(), project, "started")) 
    print(environment()) 
    print(ls(environment())) 
    sprintf("address of timesheet object is %s", pryr::address(timesheet)) 
} 

new.task("Name of task") 

“pryr”库加载获得对象的内存地址。 当我们源代码,第一:

  • 全球环境
  • 对象的全球环境
  • ,并在全球的“时间表”对象的内存地址列表的名称/地址环境

被打印。

由于最后一行运行“new.task”函数,后来这三个信息被打印在new.task函数中。见分歧:

<environment: R_GlobalEnv> 
[1] "new.task" "timesheet" "varn"  
[1] "address of timesheet object is 0x365b8e8" 
<environment: 0x32ef750> 
[1] "project" "timesheet" 
[1] "address of timesheet object is 0x365dbb8" 

为了纠正这个问题,您应该superassign与“< < - ”(一个方法来修改存在于从另一个范围的全球环境中的物体)操作如下:

new.task <- function(project){ 
    timesheet <<- append(time, c(date(), project, "started")) 
} 

但也有在你的代码两个错误:

  • 您尝试通过自身附加到“时间”没有时间表,而“时间”是一个封闭,内置本功能离子。
  • 追加向量或列表的作品。但是,当您尝试附加到数据框时,它会转换为列表。

所以,正确的形式应该是这样的(你可以使用rbind以及):

timesheet[nrow(timesheet)+1,] <<- c(date(), project, "started") 

而另一种方式来修改一个全局对象不超赋值运算符是指它与它的环境如下:

timesheet <- data.frame(matrix(nrow = 0, ncol = 3)) 
varn <- c("date", "project", "status") 
colnames(timesheet) <- varn 

timesheet[1,] <- c(date(), "test", "test") 
#The above line exists because rbind was renaming the columns otherwise 

envg <- environment() 

new.task <- function(project, env = envg){ 
    env$timesheet[nrow(env$timesheet)+1,] <- c(date(), project, "started") 
} 

new.task("Name of task") 
+0

哇,是的,我的问题有几个问题。我将rbind换成了append,并且改变了所有变量名,但是我很高兴你看到了问题的根源。非常感谢你! – MokeEire