以最佳匹配方式连接多个列

时间:2018-03-16 11:34:01

标签: r

我有两个示例数据集:

data <- data.frame(
  ID = c(1:10)
  , COL1 = LETTERS[1:10]
  , COL2 = letters[1:10]
  , COL3 = as.character(10:1)
  , stringsAsFactors = FALSE
)

match <- data.frame(
  COL1 = c("A", "C", "F", "*", "F")
  , COL2 = c("a", "c", "*", "*", "*")
  , COL3 = c("10", "8", "5", "*", "*")
  , VAL = c(0.8, 0.7, 0.9, 0.85, 0.1)
  , stringsAsFactors = FALSE
)

他们看起来像:

   > data
   ID COL1 COL2 COL3
1   1    A    a   10
2   2    B    b    9
3   3    C    c    8
4   4    D    d    7
5   5    E    e    6
6   6    F    f    5
7   7    G    g    4
8   8    H    h    3
9   9    I    i    2
10 10    J    j    1

> match
  COL1 COL2 COL3  VAL
1    A    a   10 0.80
2    C    c    8 0.70
3    F    *    5 0.90
4    *    *    * 0.85
5    F    *    * 0.10
  

结果表应该将data表与match结合起来   表,以便match表中的信息最适合   data表中的行。所以,如果你看看比赛表,那里   是COL1中F的两个不同匹配。因为还有一个5英寸   COL3,值0.9应该加入。

结果如下:

   ID COL1 COL2 COL3  VAL
1   1    A    a   10 0.80
2   2    B    b    9 0.85
3   3    C    c    8 0.70
4   4    D    d    7 0.85
5   5    E    e    6 0.85
6   6    F    f    5 0.90
7   7    G    g    4 0.85
8   8    H    h    3 0.85
9   9    I    i    2 0.85
10 10    J    j    1 0.85

我为此写了一个解决方法:

library(tidyverse)

col1u <- sort(unique(match$COL1))
col2u <- sort(unique(match$COL2))
col3u <- sort(unique(match$COL3))

dataTransformed <- data %>%
  mutate(COL1 = ifelse(COL1 %in% col1u, COL1, "*")
         , COL2 = ifelse(COL2 %in% col2u, COL2, "*")
         , COL3 = ifelse(COL3 %in% col3u, COL3, "*"))

dataJoin <- inner_join(dataTransformed, match)

这很好但我不知道这种方法是否过于复杂,因为真正的数据集有更多的列。有更简单的解决方案吗?

1 个答案:

答案 0 :(得分:0)

我们可以做到

library(tidyverse)
match %>%
    summarise_at(vars(matches("COL")), funs(list(sort(unique(.))))) %>%
    map2_df(data[names(.)], ., ~ case_when(.x %in% .y[[1]] ~ .x, TRUE ~ "*")  ) %>% 
    bind_cols(data['ID'], .) %>% 
    inner_join(match)