迭代两个data.tables'行的更优雅的方法

Faa*_*ioo 0 r data.table

我开始越来越频繁地使用R,来自C/C++.出于这个原因,在使用R的数据结构时,我经常发现自己在思考C++.

在这里,我有两个data.tables,我必须迭代并更新表A中第1列和第2列的值,表B中的第2列的值,根据第1列表B表a中的第1列和第2列.

对不起这个令人困惑的描述.我试着让它变得更好

我有两个数据表(行数不同,因为它们实际上可能不同):

塔巴

     Col1     Col2
1:   TP53     CD68
2:   TP53    MPDU1
3:   TP53     PHF2
4:   TP53 KIAA0753
5:   CD68    ZBTB4
6:   CD68     CHD3
7:  MPDU1    ZBTB4
8:  MPDU1     CHD3
9:  MPDU1   SLC2A4
10: MPDU1     YBX2
11: MPDU1    AURKB
12: MPDU1 TMEM132B
13:  PHF2 C9orf129
14:  PHF2    CDH23
15:  PHF2   PTPDC1
Run Code Online (Sandbox Code Playgroud)

和TabB:

       Col3 Col4
1:   ADAM32  0
2:   ADARB2  1
3:    AGBL2  2
4:   ALOX12  3
5:  ANKRD46  4
6:    APOL1  5
7:    APOOL  6
8:     ASPA  7
9:      AUH  8
10:   AURKB  9
11:   AUTS2 10
12:    BAAT 11
Run Code Online (Sandbox Code Playgroud)

所以基本上,我想将TabA中的Col1和Col2与TabB中的Col3进行比较:如果它们相等,则将字符串替换为TabB的Col4中的数字.

我的方法,绝对是C风格:

for(i in 1:nrow(TabA)) {
    for(j in 1:nrow(TabB)) {
        if(TabA$Col1[i] == TabB$Col3[j]) { 
            TabA$Col1[i] <- TabB$Col4[j] 
        }
        if(TabA$Col2[i] == TabB$Col3[j]) { 
            TabA$Col2[i] <- TabB$Col4[j] 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以按预期工作,但我很确定有一种更优雅(更有效)的方法,利用data.table的功能.有人有建议吗?

谢谢

Nic*_*edy 5

如果您正在使用data.table原始问题(在更改问题的大量编辑之前)可以这样做:

TabA <- data.table(Col1 = sample(LETTERS, 15), Col3 = rnorm(15))
TabB <- data.table(Col2 = sample(LETTERS, 15), Col4 = rnorm(15))
setkey(TabA, Col1)
setkey(TabB, Col2)
TabA
# shows TabA before changing it
TabA[TabB, Col3 := Col4]
Run Code Online (Sandbox Code Playgroud)

我仍然发现data.table语法有点奇怪,因为当函数不修改它们的参数时,它与R中的标准行为不同.另一方面,它使简洁,内存效率和快速的代码.

重写问题的解决方案

请注意您的样本数据是无用的-没有任何的比赛TabA$Col1TabB$Col3.无论如何,这可以通过几种方式解决.

使用data.table :=运算符:

TabA[Col1 %in% TabB$Col3, Col1 := with(TabB, as.character(Col4[na.omit(match(Col1, Col3))]))]
TabA[Col2 %in% TabB$Col3, Col2 := with(TabB, as.character(Col4[na.omit(match(Col2, Col3))]))]
Run Code Online (Sandbox Code Playgroud)

使用基本R语法(也适用于data.frame):

TabA$Col1[TabA$Col1 %in% TabB$Col3] <- TabB$Col4[match(TabA$Col1[TabA$Col1 %in% TabB$Col3], TabB$Col3)]
TabA$Col2[TabA$Col2 %in% TabB$Col3] <- TabB$Col4[match(TabA$Col2[TabA$Col2 %in% TabB$Col3], TabB$Col3)]
Run Code Online (Sandbox Code Playgroud)

使用setkey和join:

TabA[, Index := 1:nrow(TabA)]
setkey(TabA, Col1)
TabA[TabB, nomatch = 0, Col1 := as.character(Col4)]
setkey(TabA, Col2)
TabA[TabB, nomatch = 0, Col2 := as.character(Col4)]
setkey(TabA, Index)
TabA[, Index := NULL]
Run Code Online (Sandbox Code Playgroud)

所有这些都假设Col1和Col2中的某些项目不匹配.如果不是这样,可以优化代码.这也是Col4必须被强迫角色的原因.

  • 我们将有两个功能(通过引用更新和默认R行为)..因为我[详细在这里](http://stackoverflow.com/a/27718317/559784)...我们还没有得到它然而. (2认同)