-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 に答える