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

Use*_*701 1 random r data.table

我有一个包含两列的data.table,比如说city和score

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
Run Code Online (Sandbox Code Playgroud)

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

akr*_*run 6

我们采取的sample(行数.N)每每个"城市",并获得行索引(.I).使用该行索引作为i,我们赋予(:=),该索引对应的"得分"为"0".

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

如果'city'只有一行,我不确定是否要用'0'代替那一行.如果我们用'0'代替

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

如果我们不想更改少于2行的"城市"的"得分",

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

或者正如@Frank评论的那样,我们可以使用sampleon .I而不是包装.I(这里我们也在改变'city'中的nrows分数<2)

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