更新联接中的值

当数据 整洁时, 它通常被组织成几个表。要合并数据进行分析,我们需要使用另一个表中的值更新一个表。

例如,我们可能有演出的销售数据,其中表演者的属性(他们的预算)和位置(人口)存储在不同的表中:

set.seed(1)
mainDT = data.table(
  p_id = rep(LETTERS[1:2], c(2,4)), 
  geo_id = sample(rep(state.abb[c(1,25,50)], 3:1)), 
  sales = sample(100, 6)
)
pDT   = data.table(id = LETTERS[1:2], budget = c(60, 75))
geoDT = data.table(id = state.abb[c(1,50)], pop = c(100, 200))

mainDT # sales data
#    p_id geo_id sales
# 1:    A     AL    95
# 2:    A     WY    66
# 3:    B     AL    62
# 4:    B     MO     6
# 5:    B     AL    20
# 6:    B     MO    17

pDT # performer attributes
#    id budget
# 1:  A     60
# 2:  B     75

geoDT # location attributes
#    id pop
# 1: AL 100
# 2: WY 200

当我们准备进行一些分析时,我们需要从这些其他表中获取变量:

DT = copy(mainDT)

DT[pDT, on=.(p_id = id), budget := i.budget]
DT[geoDT, on=.(geo_id = id), pop := i.pop]

#    p_id geo_id sales budget pop
# 1:    A     AL    95     60 100
# 2:    A     WY    66     60 200
# 3:    B     AL    62     75 100
# 4:    B     MO     6     75  NA
# 5:    B     AL    20     75 100
# 6:    B     MO    17     75  NA

采用 copy 是为了避免污染原始数据,但我们可以直接在 mainDT 上工作。

使用单独表的优点

关于整洁数据的论文中介绍了这种结构的优点,但在此背景下:

  1. *追踪丢失的数据。*只有在合并中匹配的行才会收到分配。我们上面没有关于 geo_id == "MO" 的数据,因此我们的最终表格中的变量是 NA。如果我们意外地看到这样的缺失数据,我们可以追溯到 geoDT 表中缺少的观察,并从那里调查我们是否有可以解决的数据问题。

  2. *可理解性。*在建立我们的统计模型时,记住 budget 对每个表演者来说都是不变的可能是很重要的。一般而言,了解数据结构会带来好处。

  3. *内存大小。*可能存在大量的执行者和位置属性,这些属性不会在统计模型中结束。这样,我们不需要将它们包含在用于分析的(可能是大量的)表中。

以编程方式确定列

如果 pDT 中有很多列,但我们只想选几个,我们可以使用

p_cols = "budget"
DT[pDT, on=.(p_id = id), (p_cols) := mget(sprintf("i.%s", p_cols))]

创建列的文档所述(p_cols) := 周围的括号是必不可少的。