我需要从日期中为每个唯一ID采样一个位置,并且我不想进行替换采样。我的挂断电话是我也不想重复日期
df<-data.frame(id<-c(1,1,1,1,1,1,2,2,2,2,3,3,3,3),
date=c(2020-01-01,2020-01-01,2020-01-01,2020-01-02,2020-01-02,2020-01-02, 2020-01-02,2020-01-02,2020-01-03,2020-01-03,2020-01-04,2020-01-03-4,2020-01-04,2020-01-05,2020-01-06,2020-01-06,2020-01-07,2020-01-07),
location<-c("xy","xy","xy","xy","xy","xy","xy","xy","xy","xy","xy","xy","xy","xy","xy","xy","xy","xy"))
view(df)
这是我能得到的最接近的
df2<-df %>%
group_by(day) %>%
sample_n(1, replace = F) %>%
group_by(ID) %>%
sample_n(1,replace = F)
但是在较大的数据集上,这无法对我需要从中采样的所有可用ID进行采样(尤其是几天范围较小的ID。我觉得应该在那里有一个for循环,我只是没有我自己无法提出。
我认为,这样做的快速启发法可能会在采样中容易产生分布偏差,因此也许您会全力以赴。从技术上讲,不能保证这会在合理的时间内为您提供所需的信息(取决于您的数据)。或完全没有。
您有两个约束:
我假设日期比ID多,否则将是徒劳的。
让我们将第一个约束(id
)保留为福音,并进行迭代直到解决第二个约束:
### just for this answer ... do not do this in production
set.seed(42) # R-3.5.3
iter <- 100 # prevent a near-infinite loop
FOUND <- FALSE
while (!FOUND && iter > 0) {
samp <- do.call(rbind, by(df, df$id, function(z) z[sample(nrow(z), 1),]))
### dplyr analog
# samp <- group_by(df, id) %>% sample_n(1) %>% ungroup()
FOUND <- length(unique(samp$date)) == nrow(samp)
iter <- iter - 1L
}
FOUND
# [1] TRUE
iter
# [1] 98
samp
# id date location
# 1 1 2020-01-02 xy
# 2 2 2020-01-03 xy
# 3 3 2020-01-04 xy
# 4 4 2020-01-06 xy
显然,这将使用较大的数据集,但如果理论上存在,最终应找到可接受的样本。