我开始越来越频繁地使用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的功能.有人有建议吗?
谢谢
如果您正在使用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$Col1在TabB$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必须被强迫角色的原因.