#r #dplyr
Вопрос:
У меня есть следующие кадры данных:
df_start <- tibble(
id = 1:4,
codes = c("a, d", "d, e", "e, a", "e"),
)
df_mapping <- tibble(
code = c("a", "b", "c", "d", "e"),
value = c("first", "first", "first", "second", "third")
)
Теперь я хочу сопоставить коды df_start$с кодом df_mapping$, чтобы получить связанное значение кода.
Поэтому, если код df_mapping$появляется в кодах df_start$, он должен получить соответствующее значение, при этом значения имеют определенный порядок (если возможны как «первый», так и «второй», он должен быть «первым». Таким образом, результат должен быть:
df_start_end <- tibble(
id = 1:4,
codes = c("a, d", "d, e", "e, a", "e"),
value = c("first", "second", "first", "third")
)
Вопрос в том, как это сделать? На практике существует ~300 уникальных кодов df_mapping$, ~2500 уникальных кодов df_start$и ~10 уникальных значений df_mapping$.
Я могу сделать что-то вроде следующего, но это кажется громоздким. Есть ли более разумный способ сделать это?
df_mapping <- df_mapping %>%
mutate(order = case_when(
value == "first" ~ 1,
value == "second" ~ 2,
value == "third" ~ 3
))
df_start <- df_start %>%
mutate(codes_backup = codes) %>%
separate_rows(
codes,
sep = ", ")
df_start_end <- df_start %>%
left_join(df_mapping, by = c("codes" = "code")) %>%
group_by(codes_backup) %>%
filter(value == min(value)) %>%
ungroup() %>%
mutate(codes = codes_backup) %>%
select(-c(codes_backup, order))
Ответ №1:
Это похоже на ваш подход, но без создания временной переменной.
library(dplyr)
library(tidyr)
df_start %>%
separate_rows(codes, sep = ',\s*') %>%
left_join(df_mapping, by = c('codes' = 'code')) %>%
arrange(id, codes) %>%
group_by(id) %>%
summarise(codes = toString(codes),
value = na.omit(value)[1])
# id codes value
# <int> <chr> <chr>
#1 1 a, d first
#2 2 d, e second
#3 3 a, e first
#4 4 e third
Комментарии:
1. Спасибо за ответ, это работает только в том случае, если коды df_start$и порядок отображения df_mapping в алфавитном порядке, верно?
2. Да, это верно. Если порядок не является алфавитным, вы можете создать новый столбец с именем
order
df_mapping
, т. е.df_mapping <- df_mapping %>% mutate(order = row_number())
, и теперь упорядочить его в соответствии с этим столбцом.