R 使用另一个数据表中列的值更新一个数据表中的NAs列
我看过一篇关于这个话题的类似文章,但无法理解解决方案。基本上,我有一个带有分数和一些NAs的数据表(DT1)。如果存在“NA”,我希望流程引用另一个数据(DT2)表,该表在两个表(tract)中都有一个公共列,然后用DT2的得分列的值更新DT1中的NA。我之所以选择数据表类,是因为我认为它是一个有效的选择 DT1 DT2 我们为一些data.table概念创建了新的(更全面的)。看看我们正在研究的其他小插曲。我正在研究连接的小插曲,完成后有望更好地澄清这些类型的问题R 使用另一个数据表中列的值更新一个数据表中的NAs列,r,reference,data.table,R,Reference,Data.table,我看过一篇关于这个话题的类似文章,但无法理解解决方案。基本上,我有一个带有分数和一些NAs的数据表(DT1)。如果存在“NA”,我希望流程引用另一个数据(DT2)表,该表在两个表(tract)中都有一个公共列,然后用DT2的得分列的值更新DT1中的NA。我之所以选择数据表类,是因为我认为它是一个有效的选择 DT1 DT2 我们为一些data.table概念创建了新的(更全面的)。看看我们正在研究的其他小插曲。我正在研究连接的小插曲,完成后有望更好地澄清这些类型的问题 想法是首先在tract列的
想法是首先在
tract
列的DT1
上设置setkey()
setkey(DT1, tract)
在data.tables中,形式为x[i]
的联接需要x
的键,但不一定需要i
的键。这将导致两种情况:
- 如果
i
也设置了键--i
的第一个键列与x
的第一个键列匹配,第二个键列与第二个键列匹配,依此类推
- 如果
i
未设置键--i
的第一列与x
的第一列键匹配,i
的第二列与x
的第二列键匹配,依此类推
在这种情况下,由于i
中的第一列也是tract
,我们将跳过i
上的设置键
然后,我们执行形式为x[i]
的联接。通过这样做,对于每个i
计算x
中的匹配行索引,然后将联接结果具体化。但是,我们不希望整个联接结果成为新的data.table。相反,我们希望在那些匹配行上用DT2
更新DT1
的CreditScore
列
在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
部分在DT1
中为DT2
中的每一行查找匹配的行。如果存在匹配,我们希望DT2
的值在DT1
中更新。我们通过使用i.CreditScore
——它指的是DT2
的CreditScore
列(i.
是一个前缀,用于区分x
和i
data.tables之间名称相同的列)
更新:正如评论中指出的,上述解决方案还将更新DT1
中的非NA值。因此,方法如下:
DT1[is.na(CreditScore), CreditScore := DT2[.(.SD), CreditScore]]
在DT1
中的CreditScore
为NA
的行上,将DT1
中的CreditScore
替换为从DT2[.(.SD]的联接中获得的CreditScore
中的值
,其中.SD
对应于data.table的子集,该表包含CreditScore
为NA
的所有行
HTH如果您使用的是data.table
包,您需要在问题中明确这一点。我不清楚您是指特定于data.table
的数据结构还是基本结构data.frame
。有什么原因(例如大小/内存问题)不能将两个表合并并使用ifelse()
创建一个具有适当值的新列?@Alex,是的。他也可以将数据加载到Excel中,然后做一个vlookup
,不是吗?更具体地说,数据。table
可以执行二进制连接,并在连接时通过引用更新列。这比合并+更有效e> ifelse
是由大数据集上的几个因素决定的。感谢您的评论。是的,我选择使用data.table软件包的主要原因是它的总体效率。如果不需要,我不想在DT1中添加其他列。我将尝试下面的答案,看看它是如何工作的……谢谢,干杯!我使用信用卡是正确的吗对于每个匹配的tract
,从DT2
中获得的分数?根据我对OP的理解,DT2
值只有在DT1
中为NA
时才应取。在给出的示例中,这并不重要,因为对于公共记录,两个表中的DT1
值都是635。如果它们不同,如何计算DT1
值保留?有人告诉我,.SD
在尝试实现此解决方案时被锁定。@MichaelChirico是的,我看到了相同的行为,无法理解它何时被锁定,何时未被锁定。例如,它没有被锁定,但它被锁定。不知道…@Davidernburg-hmm,闻起来像是一个bug,我相信这意味着你只需要设置同时输入DT2
DT1[DT2, CreditScore := i.CreditScore]
# tract CreditScore
# 1: 36067013000 777
# 2: 36083052304 663
# 3: 36083052403 650
# 4: 36091062602 335
# 5: 36107020401 635
DT1[is.na(CreditScore), CreditScore := DT2[.(.SD), CreditScore]]