使用 data.table 将 table 中的列值替换为基于 R 中匹配项的查找值
Replace column values in table with values from lookup based on matches in R using data.table
我想用 lookup 列中匹配的相应值替换 table 列中的值。我通过 data.table 包“按引用分配”实现了这一点,一个接一个地取一个值(并且它是替换值),但我认为我可以做一些更模块化的事情。
总而言之,我是这样做的:
# Build a table and a lookup
code<- c("ABC","EBC","ABC","EBC","OOO","PPP","ABC")
sn <- c(1:7)
old<- c("ABC","EBC")
new<- c("CBa","CBe")
lookup <- data.frame(old,new)
table <-data.frame(code,sn)
# Set data.table as TRUE for both
setDT(table)
setDT(lookup)
# Attempt reassignment
table[code %in% lookup$old, code := lookup$new[which(lookup$old==code)]]
table
..我明白了:
> table
code sn
1: CBa 1
2: CBe 2
3: <NA> 3
4: <NA> 4
5: OOO 5
6: PPP 6
7: <NA> 7
然而,我真正希望的是这样的结果:
> table
code sn
1: CBa 1
2: CBe 2
3: CBa 3
4: CBe 4
5: OOO 5
6: PPP 6
7: CBa 7
本质上:替换是根据查找分配的所有值(不仅仅是前两个)进行的。我错过了什么?我曾尝试寻找其他解决方案,但建议似乎并不是我想要的。感谢任何答案。
我们可以从 table 中加入 on
'code' 和 'old' 并分别查找
table[lookup, code := new, on = .(code = old)]
-输出
table
code sn
1: CBa 1
2: CBe 2
3: CBa 3
4: CBe 4
5: OOO 5
6: PPP 6
7: CBa 7
基础 R 选项可以工作(但强烈推荐 ,超级优雅!)
transform(
table,
code = replace(
code,
code %in% lookup$old,
setNames(lookup$new, lookup$old)[code][code %in% lookup$old]
)
)
这给出了
code sn
1: CBa 1
2: CBe 2
3: CBa 3
4: CBe 4
5: OOO 5
6: PPP 6
7: CBa 7
或更长的 data.table
选项
> lookup[table, on = .(old = code)][, new := fcoalesce(new, old)][, old := NULL][]
new sn
1: CBa 1
2: CBe 2
3: CBa 3
4: CBe 4
5: OOO 5
6: PPP 6
7: CBa 7
我想用 lookup 列中匹配的相应值替换 table 列中的值。我通过 data.table 包“按引用分配”实现了这一点,一个接一个地取一个值(并且它是替换值),但我认为我可以做一些更模块化的事情。
总而言之,我是这样做的:
# Build a table and a lookup
code<- c("ABC","EBC","ABC","EBC","OOO","PPP","ABC")
sn <- c(1:7)
old<- c("ABC","EBC")
new<- c("CBa","CBe")
lookup <- data.frame(old,new)
table <-data.frame(code,sn)
# Set data.table as TRUE for both
setDT(table)
setDT(lookup)
# Attempt reassignment
table[code %in% lookup$old, code := lookup$new[which(lookup$old==code)]]
table
..我明白了:
> table
code sn
1: CBa 1
2: CBe 2
3: <NA> 3
4: <NA> 4
5: OOO 5
6: PPP 6
7: <NA> 7
然而,我真正希望的是这样的结果:
> table
code sn
1: CBa 1
2: CBe 2
3: CBa 3
4: CBe 4
5: OOO 5
6: PPP 6
7: CBa 7
本质上:替换是根据查找分配的所有值(不仅仅是前两个)进行的。我错过了什么?我曾尝试寻找其他解决方案,但建议似乎并不是我想要的。感谢任何答案。
我们可以从 table 中加入 on
'code' 和 'old' 并分别查找
table[lookup, code := new, on = .(code = old)]
-输出
table
code sn
1: CBa 1
2: CBe 2
3: CBa 3
4: CBe 4
5: OOO 5
6: PPP 6
7: CBa 7
基础 R 选项可以工作(但强烈推荐
transform(
table,
code = replace(
code,
code %in% lookup$old,
setNames(lookup$new, lookup$old)[code][code %in% lookup$old]
)
)
这给出了
code sn
1: CBa 1
2: CBe 2
3: CBa 3
4: CBe 4
5: OOO 5
6: PPP 6
7: CBa 7
或更长的 data.table
选项
> lookup[table, on = .(old = code)][, new := fcoalesce(new, old)][, old := NULL][]
new sn
1: CBa 1
2: CBe 2
3: CBa 3
4: CBe 4
5: OOO 5
6: PPP 6
7: CBa 7