IDと金額の2つの変数を持つデータセットがあります。サンプリングされた金額の合計が元の金額の合計を超えるまで、レコードを(置換して)サンプリングしたいと思います。
動作するサンプルコードがありますが、より良い方法はありますか?大きなデータセットで最終的に100Kの反復を実行したいのですが、私の方法は不格好なようです。
以下のコードでは、3回の反復を実行しています。
set.seed(7777)
df <- data.frame(ID = seq(1,5),
AMT = sample(1:100, 5, replace = T))
threshold <- sum(df$AMT)
output <- NULL
for (i in 1:3) {
repeat{
sel <- df[sample(nrow(df), size = 1),]
sel <- cbind(iter=i, sel)
output <- rbind(output,
sel)
check_sum <- subset(output, iter == i)
if(sum(check_sum$AMT) > threshold) break
}
}
再帰(自分自身を呼び出す関数)を使用できます。また、すべてのサンプリング結果を保存する必要はありません(ここでは行番号のみを保存します)。
set.seed(7777)
df <- data.frame(ID = 1:5,AMT = sample(1:100, 5, TRUE))
threshold <- sum(df$AMT)
# Specify N not to call it multiple times
N <- nrow(df)
repeatUntilSum <- function(input = NULL) {
# Sample one row number and join with input
result <- c(sample(N, 1), input)
# Check if still too low
if (sum(df$AMT[result]) <= threshold) {
# Run function again
repeatUntilSum(result)
} else {
# Return full sampled result
return(df[result, ])
}
}
サンプリングn
時間を実行するには、を使用しますlapply
(を使用して簡単に結合できるリストを返しますdata.table::rbindlist
)。
data.table::rbindlist(lapply(1:3, repeatUntilSum), idcol = "iter")
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加