为什么我的功能不能保存我的作业?

时间:2013-03-18 23:21:25

标签: r function random subset assign

f1 <- function(x) {
   zx1 <- sample(1:nrow(zone4[[x]]), nrow(zone4[[x]]), replace=F)
   zone4[[x]]$randnums <- zx1
}

f1(1)

## DOESN'T UPDATE zone4[[1]]

zx2 <- sample(1:nrow(zone4[[1]]), nrow(zone4[[1]]), replace=F)

zone4[[1]]$randnums <- zx2

## DOES UPDATE zone[[1]]

如果我创建一个如上所示的函数f1(),则不会更新对象'zone4 [[x]]'。但是,如果我运行与上面相同的命令但显式地声明'x',如下所示,则更新对象'zone4 [[x]]'。为什么会这样?我想知道,因为我想运行代码的迭代。如果在上面的函数f1()的定义中我写了“names(zone4 [[x]])”,那么我得到的输出告诉我该函数做了它应该做的,但是当再次查询时,zone [[ x]]似乎没有变化。谢谢您的帮助。这个想法是为给定年份和另一个变量区域的数据集的每个子集创建随机数。数据集最初是单个数据框,但我使用split()函数根据年份和区域分离数据,其中有4个。也许有更好的方法将随机数分配给特定的数据子集而不用使用split()函数?

1 个答案:

答案 0 :(得分:5)

R函数通常没有副作用(即改变全局对象中的东西)

这是一件好事(大部分时间因为我们不希望出现意想不到的后果)

惯用法是将结果分配给新对象(它可以与覆盖原始对象的名称相同)

f1 <- function(x) {
  zx1 <- sample(1:nrow(zone4[[x]]), nrow(zone4[[x]]), replace=F)
  zone4[[x]]$randnums <- zx1
  # usually a good idea to return the complete object
  # especially when a replacement function (in your case `[[<-`)
  # is the last one called
  return(zone4)
}

zone4 <- f1(1)

另一种方法是使用data.table

library(data.table)
zone4 <- lapply(zone4, as.data.table)

f1 <- function(x) {
  zone4[[x]][,randnums := sample(.N)]
  invisible(NULL)
}