使用data.table按组抽样而不重复

Car*_*sta 4 r data.table

我将使用一个假设的场景来说明这个问题。这是一张桌子,上面有音乐家和他们演奏的乐器,还有一张表,其中有乐队的作品:

musicians <- data.table(
  instrument = rep(c('bass','drums','guitar'), each = 4),
  musician = c('Chas','John','Paul','Stuart','Andy','Paul','Peter','Ringo','George','John','Paul','Ringo')
)

band.comp <- data.table(
  instrument = c('bass','drums','guitar'),
  n = c(2,1,2)
)
Run Code Online (Sandbox Code Playgroud)

为了避免争论谁最好用哪种乐器,乐队将按分类组装。这是我的做法:

musicians[band.comp, on = 'instrument'][, sample(musician, n), by = instrument]

   instrument     V1
1:       bass   Paul
2:       bass   Chas
3:      drums   Andy
4:     guitar   Paul
5:     guitar George
Run Code Online (Sandbox Code Playgroud)

问题是:由于有些音乐家演奏的乐器不止一种,因此可能会吸引一个人不止一次。

可以建立一个for循环,为每个随后的乐器子集吸引音乐人,然后从表的其余部分中消除音乐人。但我想提出有关如何使用data.table进行操作的建议。主要是因为我需要用这种逻辑在现实生活中解决的这类问题涉及具有成千上万行的数据库。同时也是因为我试图更好地理解data.table语法。

作为参考,我尝试了来自Andrew Brooks博客的一些技巧,但无法提出解决方案。

Jua*_*íaz 5

这可能是一个解决方案,首先您选择音乐家的乐器,然后再选择样本音乐家。但是可能是,当为每个音乐家选择一种乐器时,您的样本数量大于总数,那么您会得到一个错误(但是在您的真实数据中,这可能不是问题)。

musicians[, .(instrument = sample(instrument, 1)), by = musician][band.comp, on = 'instrument'][, sample(musician, n), by = instrument]
Run Code Online (Sandbox Code Playgroud)

  • 沮丧的人感到困惑。这似乎是一个很好的解决方案。 (4认同)