在数据表 R 上查找内部值

Lookup an internal value on a datatable R

我有一个数据table,有两个标识符和一个像这样的值:

dt <- data.table(id=LETTERS[1:8], id_opposite=c("B","A","H","D", "F","C", "E","G"), value = 1:8)
dt
   id id_opposite value
1:  A           B     1
2:  B           A     2
3:  C           H     3
4:  D           D     4
5:  E           F     5
6:  F           C     6
7:  G           E     7
8:  H           G     8

我想添加一个列,其中包含对应于 id_opposite 的值。所以对于第一行,那将是 2,对于第二行,它将是 1。即我想要的输出是这样的:

  id id_opposite value value_opposite
1  A           B     1              2
2  B           A     2              1
3  C           H     3              8
4  D           D     4              4
5  E           F     5              6
6  F           C     6              3
7  G           E     7              5
8  H           G     8              7

我知道我可以通过从 dt 构造一个查找 table,然后将它与 dt 合并来做到这一点,但是有没有办法在数据 table 中做,比如 [=13] =]

dt[, value_opposite := dt[some-function-of-id_opposite-and-value]]

感谢您的建议!

我喜欢使用 dplyr 包,因为我认为它使用更直观和可读的语法。

library(dplyr)
dt <- data.frame(id=LETTERS[1:8], id_opposite=c("B","A","H","D", "F","C", "E","G"), value = 1:8)

# Simpler solution
dt %>%
  inner_join(dt, by = c("id_opposite" = "id")) %>%
  select(id, id_opposite, value = value.x, opposite_value = value.y) %>%
  print(row.names = F)

# Alternative solution    
dt %>%
  inner_join(select(dt, id, value_opposite=value), by = c("id_opposite" = "id")) %>%
  print(row.names = F)

输出

 id id_opposite value value_opposite
  A           B     1              2
  B           A     2              1
  C           H     3              8
  D           D     4              4
  E           F     5              6
  F           C     6              3
  G           E     7              5
  H           G     8              7

一个简单的自连接:

dt[dt, value_opposite := i.value, on = .(id_opposite = id)]

对于这个特殊情况:

dt$value_opposite <- match(dt$id_opposite, dt$id)

但是如果您的值与索引不同,您也可以这样做:

dt$value_opposite <- dt$value[match(dt$id_opposite, dt$id)]
dt
   id id_opposite value value_opposite
1:  A           B     1              2
2:  B           A     2              1
3:  C           H     3              8
4:  D           D     4              4
5:  E           F     5              6
6:  F           C     6              3
7:  G           E     7              5
8:  H           G     8              7