【问题标题】:Update a column of NAs in one data table with the value from a column in another data table用另一个数据表中一列的值更新一个数据表中的一列 NA
【发布时间】:2015-03-05 22:29:33
【问题描述】:

我看到过有关此主题的类似帖子,但无法理解解决方案。本质上,我有一个带有分数和一些 NA 的数据表(DT1)。无论哪里有“NA”,我都想要一个引用另一个数据 (DT2) 表的过程,该表在两个表 (tract) 中都有一个公共列,然后用 DT2 的 score 列的值更新 DT1 中的 NA。我选择数据表类是因为我认为它是一个有效的选择。

DT1

         tract CreditScore    
1: 36107020401         635  
2: 36083052403          NA  
3: 36091062602          NA  
4: 36067013000          NA  
5: 36083052304          NA  

DT2

         tract CreditScore  
1: 36107020401         635  
2: 36083052403         650  
3: 36091062602         335  
4: 36067013000         777  
5: 36083052304         663  

【问题讨论】:

  • 如果您使用的是data.table 包,您需要在问题中明确说明。我不清楚您是指特定于data.table 的数据结构还是data.frame 的基本结构。是否有原因(例如大小/内存问题)您不能只合并两个表并使用ifelse() 创建一个具有适当值的新列?
  • @Alex,是的。他也可以将数据加载到 Excel 中并执行vlookup,不是吗?更具体地说,data.table 可以执行二进制 连接并在连接时通过引用更新列。这将比merge + ifelse 在大数据集上的几个因素更有效。
  • 感谢您的 cmets。是的,我选择使用 data.table 包的主要原因是它的整体效率。如果不需要,我不想在 DT1 中添加另一列。我将尝试下面的答案,看看它是如何工作的......谢谢和欢呼!

标签: r reference data.table


【解决方案1】:

我们为一些 data.table 概念创建了新的(更全面的)HTML vignettes。看看here 了解我们正在处理的其他小插曲。我正在研究连接的小插曲,完成后有望更好地澄清这些类型的问题。


这个想法是先在setkey()DT1tract 列上。

setkey(DT1, tract)

在 data.tables 中,x[i] 形式的连接需要 x 的键,但不一定是 i。这会导致两种情况:

  • 如果i 也有键集——i 的第一个键列与x 的第一个键列匹配,第二个与第二个匹配,依此类推..

  • 如果i 没有键集——i 的第一列与x 的第一列 key 匹配,i 的第二列针对x 的第二个 key 列,依此类推..

在这种情况下,由于i 中的第一列也是tract,我们将跳过i 上的设置键。

然后,我们执行x[i] 形式的连接。通过这样做,对于每个i,计算x 中的匹配行索引,然后实现连接结果。但是,我们不希望将整个连接结果作为新的 data.table。相反,我们想在那些匹配的行上用DT2 更新DT1CreditScore 列..

在 data.tables 中,我们可以在加入时执行该操作,方法是在 j 中提供表达式,如下所示:

DT1[DT2, CreditScore := i.CreditScore]
#          tract CreditScore
# 1: 36067013000         777
# 2: 36083052304         663
# 3: 36083052403         650
# 4: 36091062602         335
# 5: 36107020401         635

DT1[DT2 部分为DT2 中的每一行查找DT1 中的匹配行。如果有匹配,我们希望DT2 的值在DT1 中更新。我们通过使用i.CreditScore 来实现这一点——它引用DT2CreditScore 列(i. 是用于区分xi data.tables 之间名称相同的列的前缀)。


更新:正如在 cmets 下所指出的,上述解决方案还将更新 DT1 中的非 NA 值。因此,这样做的方法是:

DT1[is.na(CreditScore), CreditScore := DT2[.(.SD), CreditScore]]

DT1 中的CreditScoreNA 的那些行上,将DT1 中的CreditScore 替换为从DT2[.(.SD)] 的连接获得的CreditScore 中的值,其中.SD 对应于data.table 的子集,其中包含 CreditScoreNA 的所有行。

HTH

【讨论】:

  • 我对每个匹配的tract 使用来自DT2CreditScore 是否正确?据我了解,只有在DT1 中为NA 时才应采用DT2 值。在给出的示例中,这无关紧要,因为在两个表中对于公共记录它都是 635。如果它们不同,如​​何保留DT1 值?
  • 我被告知 .SD 在尝试实施此解决方案时被锁定。
  • @MichaelChirico 是的,我看到了相同的行为,无法理解它何时被锁定,何时未被锁定。例如,它没有被锁定here,但它被锁定here。不知道...
  • @DavidArenburg 嗯,我闻起来像个虫子
  • 我相信这意味着你只需要在DT2中设置密钥
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-25
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多