r - 如何在另一个变量中第 n 次出现某个值时更改变量?

标签 r data.table

有一个data.table

library(data.table)
car <- data.table(no = 1:100, turn = sample(1:5,100,replace = TRUE), 
              dis = sample(1:10,100,replace = TRUE))

我想在 turn == 3 第 n 次出现时将“dis”更改为 -1 , 第三次说“转”是 3 .

我可以选择turn == 3的第三行:
car[turn == 3, .SD[3]]

但是,我无法在这一行更新“dis”:
car[turn == 3, .SD[3]][, dis := -1]

相关问答:Conditionally replacing column values with data.table .

最佳答案

一些替代方案。使用 rowidcumsum在组内创建行计数器。在 i 中将计数器添加到您的条件中.

我使用了一个稍微小一点的玩具数据集,只是为了更容易跟踪变化:

d <- data.table(x = 1:3, y = 1:12)

d[rowid(x) == 3 & x == 3, y := -1]

# @mt1022
d[cumsum(x == 3) == 3 & (x == 3), y := -1]

# @docendo discimus
d[(ix <- x == 3) & cumsum(ix) == 3, y := -1]

虽然 OP 没有提到速度是一个问题,但我仍然很好奇在更大的向量上对不同的方法进行计时。不出所料,@Frank 的方法是最快的,尤其是当要搜索的唯一值数量增加时:
frank << docendo < henrik < mt022
microbenchmark(henrik = d[rowid(x) == 3 & x == 3, y := -1],
               mt1022 = d[cumsum(x == 3) == 3 & (x == 3), y := -1],
               docendo = d[(ix <- x == 3) & cumsum(ix) == 3, y := -1],
               frank = d[d[x == 3, which = TRUE][3], y := -1], unit = "relative")

d <- data.table(x = sample(1:3, 1e6, replace = TRUE), y = 1:1e6)
# Unit: relative
#    expr      min       lq     mean   median       uq      max neval cld
#  henrik 4.417303 4.369407 4.133514 4.319839 4.329658 1.260394   100  b 
#  mt1022 5.461961 5.285562 5.174559 5.186404 5.239738 1.608712   100   c
# docendo 3.572646 3.624369 3.788678 3.589705 3.576637 1.733272   100  b 
#   frank 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000   100 a 

d <- data.table(x = sample(1:30, 1e6, replace = TRUE), y = 1:1e6)
# Unit: relative
#    expr      min       lq     mean   median       uq      max neval cld
#  henrik 22.64881 19.54375 18.81963 18.91335 19.78559 5.507692   100  bc
#  mt1022 24.58258 21.17535 19.84417 20.96256 22.76020 3.625263   100   c
# docendo 19.40044 16.75912 16.23321 16.47953 18.06264 4.234100   100  b 
#   frank  1.00000  1.00000  1.00000  1.00000  1.00000 1.000000   100 a

d <- data.table(x = sample(1:300, 1e6, replace = TRUE), y = 1:1e6)
# Unit: relative
#    expr      min       lq     mean   median       uq       max neval cld
#  henrik 31.81237 32.51122 28.79490 30.35766 28.63560  8.236282   100  b 
#  mt1022 34.71984 35.45341 33.20405 33.57394 31.50914 21.556367   100   c
# docendo 27.99046 28.15855 26.56954 26.60644 25.20044  7.847163   100  b 
#   frank  1.00000  1.00000  1.00000  1.00000  1.00000  1.000000   100 a

# Unit: milliseconds
#    expr       min        lq      mean    median       uq        max neval cld
#  henrik 60.655582 76.455531 83.061266 77.632036 78.57818 203.224042   100   c
#  mt1022 66.701182 84.133034 87.967300 84.937201 85.72464 201.167914   100   c
# docendo 52.938545 67.214360 71.558130 68.003891 68.51897 184.178346   100  b 
#   frank  1.977821  2.494039  2.629852  2.663577  2.76089   3.613905   100 a

关于r - 如何在另一个变量中第 n 次出现某个值时更改变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45914435/

相关文章:

r - 在 R 中使用 lm 时,可变长度不同错误

每次我在 R Shiny 中修改 numericInput 时都会重置 selectinput

r - I(x) := y and `:=` (I(x) = y) 之间差异的 data.table 错误

r - ggplot2 - boxplot 多个 data.frames 同时保持秩序

r - clmm后如何使用dotplot

r - R 中数据集的 "multinomial expansion"

r - R中的内部字符串缓存

r - 将变量和名称传递给 data.table 函数

R data.table J 行为

使用具有多列的 data.table 将宽改成长