我有如下示例数据:
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
,则可以使用melt
和on = ...
的连接,例如
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
解释:
- 在
dat1
的unlist
ed值上使用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