按类别修改 data.table 的随机行中的值

Modify values in random rows of a data.table by category

我有一个包含两列的 data.table,比如说城市和得分

data.table(city = sample(c("Cape Town", "New York",  "Tel Aviv"),size=15, replace = TRUE), score = sample(x=1:10, size = 15, replace=TRUE))
         city score
 1:  Tel Aviv     5
 2:  New York     5
 3:  New York     8
 4: Cape Town    10
 5:  Tel Aviv     7
 6:  New York    10
 7:  Tel Aviv     8
 8: Cape Town     2
 9:  Tel Aviv     2
10: Cape Town     2
11: Cape Town     5
12:  New York     1
13:  Tel Aviv     3
14: Cape Town     6
15:  New York     5

我想将分数更改为 0 到每个城市随机两行(即特拉维夫两行,纽约两行,等等)。请注意,每个城市总会有两行以上(我的真实数据非常大......)。理想情况下,我想要一个基于 data.table 命令的解决方案...... 谢谢!

我们每个 'city' 取 sample 行数 (.N) 并得到行索引 (.I)。使用该行索引作为 i,我们将 (:=) 对应于该索引的 'score' 分配为 '0'。

 i1 <- dt[, .I[sample(.N, 2)], by = city]$V1
 dt[i1, score:=0L]

在 'city' 只有一行的情况下,我不确定我们是否要用“0”替换该行。如果我们用 '0'

替换
  i1 <- dt[, if(.N<2) .I else .I[sample(.N,2)] ,city]$V1
  dt[i1, score:=0L]

如果我们不想为少于 2 行的 'city' 更改 'score',

  i1 <- dt[, if(.N>1) .I[sample(.N,2)] ,city]$V1
  dt[i1, score := 0L]

或者正如@Frank 评论的那样,我们可以在 .I 上获得 sample 而不是用 .I 换行(这里我们还更改了 [=30= 中 nrows 的分数) ] < 2)

  i1 <- dt[, if(.N<2) .I else sample(.I, 2) ,city]$V1
  dt[i1, score := 0L]