首页 > 解决方案 > 基于列的一部分映射值

问题描述

我有以下数据框:

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$codes 映射到 df_mapping$code 以获取代码的关联值。

因此,如果 df_mapping$code 出现在 df_start$codes 中,它应该获得关联的值,从而这些值具有一定的顺序(如果“第一”和“第二”都可能,它应该是“第一”。所以结果应该是:

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$code、~2500 个唯一的 df_start$codes 和 ~10 个唯一的 df_mapping$value。

我可以按照以下方式做一些事情,但感觉很麻烦。有没有更聪明的方法来做到这一点?

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))

标签: rdplyr

解决方案


这类似于您的方法,但没有创建临时变量。

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 

推荐阅读