识别 data.table 中的邻居

gva*_*van 5 r data.table

我有以下数据.表*:

dt <- data.table(
  LEFT  = letters[c(1:5, 10:12)],
  SELF  = letters[c(2:6, 11:13)],
  RIGHT = letters[c(3:7, 12:14)]
  )

dt <- dt[sample(nrow(dt)), ]
dt[]

#    LEFT SELF RIGHT
# 1:    e    f     g
# 2:    d    e     f
# 3:    j    k     l
# 4:    c    d     e
# 5:    l    m     n
# 6:    b    c     d
# 7:    a    b     c
# 8:    k    l     m
Run Code Online (Sandbox Code Playgroud)

LEFT 和 RIGHT 表示 SELF 的邻居。我想对表进行索引,以便对相邻的邻居进行分组和排序。理想的输出可能如下所示:

dt_out[]
#    LEFT SELF RIGHT RUN ORDER
# 1:    e    f     g   1     5
# 2:    d    e     f   1     4
# 3:    j    k     l   2     1
# 4:    c    d     e   1     3
# 5:    l    m     n   2     3
# 6:    b    c     d   1     2
# 7:    a    b     c   1     1
# 8:    k    l     m   2     2

run_1 <- dt_out[RUN == 1][order(ORDER)][["SELF"]]
run_1
# [1] "b" "c" "d" "e" "f"
Run Code Online (Sandbox Code Playgroud)

我很想编写一个函数来应用于 SELF 来识别 LEFT == SELF == RIGHT 的位置,但我认为鉴于 data.table 的按组排序功能,这是错误的途径。

*实际上,我的 data.table 有 190 万个观察值,并且没有以任何有意义的方式排序。

Tim*_*Fan 1

我们可以使用rleid%/% 2创建RUN变量,然后我们可以通过分组by RUN并获取行号1:.N来创建ORDER列。

library(data.table)

dt[,
   RUN := rleid(shift(RIGHT, type = "lag", fill = SELF[1]) == SELF) %/% 2 + 1
][,
  ORDER := 1:.N,
  by = RUN][]

#>      LEFT   SELF  RIGHT   RUN ORDER
#>    <char> <char> <char> <num> <int>
#> 1:      a      b      c     1     1
#> 2:      b      c      d     1     2
#> 3:      c      d      e     1     3
#> 4:      d      e      f     1     4
#> 5:      e      f      g     1     5
#> 6:      j      k      l     2     1
#> 7:      k      l      m     2     2
#> 8:      l      m      n     2     3
Run Code Online (Sandbox Code Playgroud)

由reprex 包于 2022 年 3 月 30 日创建(v0.3.0)