【问题标题】:Repeat sampling with replacement until exceeding threshold重复采样并替换直到超过阈值
【发布时间】:2019-01-14 22:08:20
【问题描述】:

我有一个包含 2 个变量的数据集:一个 ID 和一个金额。我想对记录进行抽样(带替换),直到抽样的金额总和超过原始金额总和。

我有可以工作的示例代码,但有更好的方法吗?我想最终在一个大型数据集上运行 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
  }
}

【问题讨论】:

    标签: r sampling


    【解决方案1】:

    您可以使用递归(调用自身的函数)。此外,您不需要存储所有采样结果(这里我们只存储行号)。

    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")
    

    【讨论】:

    • 对于 rbindlist() 函数,您似乎需要应用一个数字向量 data.table::rbindlist(lapply(1:10, repeatUntilSum), idcol = "iter") 会产生错误,但 data.table::rbindlist(lapply(rep(1,10), repeatUntilSum), idcol = "iter") 有效。不知道为什么……
    猜你喜欢
    • 2018-11-26
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 2014-08-19
    • 2020-11-21
    相关资源
    最近更新 更多