簡體   English   中英

data.table有條件地使用另一個data.table中的值替換數據

[英]data.table replace data using values from another data.table, conditionally

這類似於用另一個data.table中的值更新R.data.table中的值替換另一個data.table中的值的索引更新data.table中的值 ,除了在我的情況下,變量的數量非常大,所以我不想明確列出它們。

我所擁有的是一個大的data.table (我們將其dt_original )和一個較小的data.table (我們將其dt_newdata ),其ID是第一個的子集,並且僅具有第一個的一些變量。 我想更新中的值dt_original從值dt_newdata 對於增加的扭曲,我希望有條件地更新值-在這種情況下,僅當值dt_newdata比相應的值較大dt_original

對於可重現的示例,以下是數據。 在現實世界中,表要大得多:

library(data.table)
set.seed(0)

## This data.table with 20 rows and many variables is the existing data set
dt_original <- data.table(id = 1:20)
setkey(dt_original, id)

for(i in 2015:2017) {
  varA <- paste0('varA_', i)
  varB <- paste0('varB_', i)
  varC <- paste0('varC_', i)

  dt_original[, (varA) := rnorm(20)]
  dt_original[, (varB) := rnorm(20)]
  dt_original[, (varC) := rnorm(20)]
}

## This table with a strict subset of IDs from dt_original and only a part of
## the variables is our potential replacement data
dt_newdata <- data.table(id = sample(1:20, 3))
setkey(dt_newdata, id)

newdata_vars <- sample(names(dt_original)[-1], 4)

for(var in newdata_vars) {
  dt_newdata[, (var) := rnorm(3)]
}

這是一種使用loop和pmax ,但是必須有更好的方法,對嗎?

for(var in newdata_vars) {
  k <- pmax(dt_newdata[, (var), with = FALSE], dt_original[id %in% dt_newdata$id, (var), with = FALSE])
  dt_original[id %in% dt_newdata$id, (var) := k, with = FALSE]
}

似乎應該有一種使用連接語法的方法,也許還有前綴i. 和/或.SD或類似的名稱,但我嘗試過的任何內容都不足以在此處重復。

根據您的條件,該代碼應以當前格式運行。

dt_original[dt_newdata, names(dt_newdata) := Map(pmax, mget(names(dt_newdata)), dt_newdata)]

它連接到data.tables之間匹配的ID,然后使用:=執行分配。由於我們要返回列表,因此我使用Map通過名稱與dt_newdata匹配的data.tables列運行pmax 請注意,dt_newdata的所有名稱都必須在dt_original數據中。

遵循弗蘭克(Frank)的評論,您可以使用[-1]刪除“ Map列表項的第一列和列名,因為它們是ID,不需要計算。 Map刪除第一列可避免一次pmax傳遞,並保留id上的鍵。 感謝@ brian-stamper指出注釋中的密鑰保留。

dt_original[dt_newdata,
            names(dt_newdata)[-1] := Map(pmax,
                                         mget(names(dt_newdata)[-1]),
                                         dt_newdata[, .SD, .SDcols=-1])]

注意, [-1]的使用假定ID變量位於new_data的第一位置。 如果在其他位置,則可以手動更改索引或使用grep

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM