-1
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个。

4

1 回答 1

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)
}
于 2013-03-18T23:28:26.403 回答