我在 R 中有一个 SF 对象。它看起来如下:
Type Value Geometry
A 1 ()
A 3 ()
B 2 ()
A 1 ()
C 4 ()
在几何列中,存储面要素的几何形状。 我想对随机行进行采样,直到达到或超过
Value
列中的值之和时的阈值(假设为 5)。
如果在上例中,对第 1、4、5 行进行了采样,则采样停止。
我不确定这是否是最有效的方法,但是您可以在 for 循环中创建一个子集,删除每个步骤中选取的行,然后计算子集中值的总和,如果达到则停止门槛。我假设采样没有替换。
df1 <- read.table(text = "Type Value Geometry
A 1 ()
A 3 ()
B 2 ()
A 1 ()
C 4 ()", header = T, stringsAsFactors = F)
df1_step <- df1
df1_subset <- data.frame(matrix(ncol = ncol(df1), nrow = 0))
set.seed(123)
for(i in seq_len(nrow(df1))){
sub_id <- sample(seq_len(nrow(df1_step)), size = 1)
df1_subset <- rbind(df1_subset, df1_step[sub_id,])
df1_step <- df1_step[-sub_id,]
if (sum(df1_subset$Value) >= 5) { break }
}
## sample
df1_subset
#> Type Value Geometry
#> 3 B 2 ()
#> 2 A 3 ()
## rows that were not picked up
df1_step
#> Type Value Geometry
#> 1 A 1 ()
#> 4 A 1 ()
#> 5 C 4 ()
创建于 2023 年 11 月 10 日,使用 reprex v2.0.2
您可以使用 while 循环来检查每次迭代的总和:
library(tidyverse)
df <- tibble(type = c('a', 'a', 'b', 'a', 'c'), value = c(1, 3, 2, 1, 4))
samples <- tibble()
sample_sum <- 0
while (sample_sum < 5) {
ix <- sample(1:nrow(df), size = 1, replace = TRUE)
samples <- bind_rows(samples, slice(df, ix))
sample_sum <- sum(samples$value)
}
df <- tibble(type = c('a', 'a', 'b', 'a', 'c'), value = c(1, 3, 2, 1, 4))
set.seed(42)
df[sample(nrow(df)),] |>
mutate(cumsum = cumsum(value)) |>
filter(lag(cumsum,1, default = 0) < 5) |>
select(-cumsum)
这会随机化 DF 中的行,生成“值”的累积和,并在超过 5 的累积和限制后过滤掉所有行。
我使用“滞后”来确保您也获得超出限制的行。