У меня есть пример данных следующим образом:
library(data.table)
dat1 <- fread("code1 code2 code3
A3 B2 C1
A4 B3 C2")
dat2 <- fread("codes
A3
A4
B2
B3")
Я просто хотел бы заменить коды в dat2
на code3
из dat1
.
Желаемый результат:
dat_out <- fread("codes
C1
C2
C1
C2")
Как мне это сделать?
Это может быть один из способов сделать это:
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
Вы можете использовать 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
Объяснение:
match
для unlist
ed значения dat1
(вы также можете сосредоточиться только на выбранных столбцах).%%
(по модулю), чтобы получить оставшуюся часть целочисленного деления на nrow(dat1)
. По сути, он восстанавливает размер столбцов (релист).nrow
), отсюда и новый оператор.Мы можем использовать melt
вместе с join by on = ...
, если вы работаете с data.table
, например,
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
Вариант с именованным вектором
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