通过在每个区域随机抽取一个站点但保留不同年份的行来对数据进行子集化

Subset data by randomly sampling one Site per Region but keeping rows of different Year

这是来自 Randomly sample per group, make a new dataframe, repeat until all entities within a group are sampled

的扩展问题

根据下面的示例数据,我想通过从每个区域随机抽取一个站点来生成多个数据帧。要制作另一个数据框,请在没有替换的情况下随机抽取另一个 Site 样本;也就是说,无法对在任何先前采样中采样的给定区域的相同站点进行采样。因此,数据框的数量将与区域内站点的数量一样多。我的这部分问题在上面的 link 中得到了回答(尽管我在那个网站上找不到接受该答案的复选标记)。

我的问题是关于我的另一个数据框,该数据框包含给定站点多年的数据。我希望每个数据框都包含唯一的区域-站点组合(在上面的 link 中回答)但包含所有年份的数据。这是一个示例数据(给定地区的年数和地点存在一些差异):

mydf <- read.table(header = TRUE, text = 'V1 V2 Region Site Year
  5 1 A X1 2000
  1 1 A X1 2001
  5 6 A X2 2000
  2 2 A X2 2001
  8 9 A X3 2000
  5 5 A X3 2001
  3 3 B X1 2000
  2 3 B X1 2001
  3 1 B X2 2000
  4 4 B X2 2001
  7 8 B X3 2000
  1 2 C X1 2000
  9 4 C X1 2001
  4 5 C X2 2000
  6 7 C X2 2001')

以下是一些预期的数据帧:

V1 V2 Region Site Year
5  1      A   X1 2000
1  1      A   X1 2001
3  1      B   X2 2000
4  4      B   X2 2001
1  2      C   X1 2000
9  4      C   X1 2001

V1 V2 Region Site Year
8  9      A   X3 2000
5  5      A   X3 2001
3  3      B   X1 2000
2  3      B   X1 2001
4  5      C   X2 2000
6  7      C   X2 2001

我尝试修改上面link中提供的代码,但没有成功。这是我试过的代码

library(data.table)
dt <- setDT(mydf)
dt <- dt[sample(.N)]
dt <- unique(dt, by = c('Year','Region'))
dt[, .SD[1], by=c("Region","Year")]

由于每个'Region/Site'组合没有重复的'Year',转换为'data.table'(setDT(mydf))后,按'Region'分组,我们sample'Site'的unique个元素,获取采样元素等于'Site'的行索引(.I),提取行索引($V1), 用它来对数据集的行进行子集化

setDT(mydf)[mydf[,  .I[Site ==sample(unique(Site), 1)], .(Region)]$V1]
#   V1 V2 Region Site Year
#1:  5  1      A   X1 2000
#2:  1  1      A   X1 2001
#3:  3  1      B   X2 2000
#4:  4  4      B   X2 2001
#5:  1  2      C   X1 2000
#6:  9  4      C   X1 2001

如果我们需要复制这个,我们可以使用replicate

setDT(mydf)
lst <- replicate(5, mydf[mydf[,  .I[Site ==sample(unique(Site), 1)],
                .(Region)]$V1], simplify = FALSE)

更新

如果我们需要删除已经发生的 'Site',那么在我们创建 [=20= data.table ('lst1') 的 ] 每个 'Region'

采样 'Site'
setDT(mydf)
mydf1 <- copy(mydf)
lst1 <- vector("list", 3)
for(i in 1:3){
  tmp <- mydf[, .(Site = sample(unique(Site), 1)), Region]
  lst1[[i]] <-  mydf[tmp, on = .(Region, Site)]
   mydf <- mydf[mydf[tmp, Site != i.Site, on = .(Region)]]
 } 

lst1
#[[1]]
#   V1 V2 Region Site Year
#1:  5  6      A   X2 2000
#2:  2  2      A   X2 2001
#3:  3  3      B   X1 2000
#4:  2  3      B   X1 2001
#5:  4  5      C   X2 2000
#6:  6  7      C   X2 2001

#[[2]]
#   V1 V2 Region Site Year
#1:  5  1      A   X1 2000
#2:  1  1      A   X1 2001
#3:  7  8      B   X3 2000
#4:  1  2      C   X1 2000
#5:  9  4      C   X1 2001

#[[3]]
#   V1 V2 Region Site Year
#1:  8  9      A   X3 2000
#2:  5  5      A   X3 2001
#3:  3  1      B   X2 2000
#4:  4  4      B   X2 2001