r语言 - 如果列值与另一个数据集中的两个列中的一个匹配,则替换列值



我有如下示例数据:

library(data.table)
dat1 <- fread("code1 code2 code3
A3     B2   C1
A4     B3   C2")
dat2 <- fread("codes
A3  
A4
B2
B3")

我只想将dat2中的代码替换为dat1中的code3

所需输出:

dat_out <- fread("codes
C1  
C2
C1
C2")

我该怎么做?

如果您正在使用data.table,则可以使用melton = ...的连接,例如

dat2[
melt(dat1, id.var = "code3"), 
.(codes = code3),
on = c(codes = "value")
]

,


> dat2[melt(dat1, id.var = "code3"), .(codes = code3), on = c(codes = "value")]
codes
1:    C1
2:    C2
3:    C1
4:    C2

其中melt(dat1, id.var = "code3")看起来像

> melt(dat1, id.var = "code3")
code3 variable value
1:    C1    code1    A3
2:    C2    code1    A4
3:    C1    code2    B2
4:    C2    code2    B3

您可以使用match:

`%r%`<- function(x, y) replace(x %% y, x %% y == 0, y)
dat2[, codes := dat1$code3[match(dat2$codes, unlist(dat1)) %r% nrow(dat1)]]
#   codes
#1:    C1
#2:    C2
#3:    C1
#4:    C2

解释:

  • dat1unlisted值上使用match(您也可以只关注选定的列)。
  • 你可以使用%%(模)得到nrow(dat1)的整数除法的剩余部分。基本上,它恢复列的大小(rellist)。
  • 问题是,它创建的值为0,我们需要2(或nrow),因此新的操作符

可以这样做:

library(tidyverse)
dat2 %>% 
inner_join(dat1 %>% pivot_longer(!code3), by = c('codes'='value')) %>%
select(!name) %>%
mutate(codes = coalesce(!!!rev(.))) %>%
select(codes)
codes
1:    C1
2:    C2
3:    C1
4:    C2

一个名为vector的选项

dat2[, codes := setNames(rep(dat1$code3, 2), unlist(dat1[, 1:2]))[codes]]

与产出

> dat2
codes
<char>
1:     C1
2:     C2
3:     C1
4:     C2

另一种基于match函数的解决方案:

dat2[, codes := dat1[, rep(code3, 2)[match(codes, c(code1, code2))]]]
codes
1:     C1
2:     C2
3:     C1
4:     C2

最新更新