【问题标题】:Join multiple columns with multiple lookup tables使用多个查找表连接多个列
【发布时间】:2022-01-09 15:04:31
【问题描述】:

我的任务是在 R 中从 SAS 重现一个流程。在过去的 71 个月中,我有 1 个包含 140 万行和 156 列的表。列中只有 ID,它们将被替换为文本。

为此有 60 个查找表。其中一些被多次使用,一些只被使用一次。

我无法显示真实数据,但这里是表格外观的一个小示例。:

df <-tibble(contract_id = c(1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010),
            feature_a = c(1, 2, 3, 1, 2, 3, 1, 2, 3, 1),
            feature_b = c(3, 2, 1, 3, 2, 1, 3, 2, 1, 3),
            feature_c = c(2, 3, 1, 2, 3, 1, 2, 3, 1, 2),
            feature_d = c(1, 2, 1, 2, 1, 2, 1, 2, 1, 2),
            feature_e = c(2, 1, 2, 1, 2, 1, 2, 1, 2, 1),
            feature_f = c(2, 2, 1, 1, 2, 2, 1, 1, 2, 2))

   contract_id feature_a feature_b feature_c feature_d feature_e feature_f
         <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
         1001         1         3         2         1         2         2
         1002         2         2         3         2         1         2
         1003         3         1         1         1         2         1
         1004         1         3         2         2         1         1
         1005         2         2         3         1         2         2
         1006         3         1         1         2         1         2
         1007         1         3         2         1         2         1
         1008         2         2         3         2         1         1
         1009         3         1         1         1         2         2
         1010         1         3         2         2         1         2

这些是 60 个查找表中的 2 个,被多次使用,例如 lookup_a 使用了 8 次,lookup_b 使用了 15 次:

lookup_a = tibble(id = c(1, 2, 3),
                 value = c("yes", "no", "yes, mandatory"))
                 
lookup_b = tibble(id = c(1, 2),
                  value = c("yes", "no"))

这是所需结果的外观(feature_a - c 使用 lookup_a 和 feature_d - f 使用 lookup b):

df_expected <-tibble(contract_id = c(1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010),
                     feature_a = c("yes", "no", "yes, mandatory", "yes", "no", "yes, mandatory", "yes", "no", "yes, mandatory", "yes"),
            feature_b = c("yes, mandatory", "no", "yes", "yes, mandatory", "no", "yes", "yes, mandatory", "no", "yes", "yes, mandatory"),
            feature_c = c("no", "yes, mandatory", "yes", "no", "yes, mandatory", "yes", "no", "yes, mandatory", "yes", "no"),
            feature_d = c("yes", "no", "yes", "no", "yes", "no", "yes", "no", "yes", "no"),
            feature_e = c("no", "yes", "no", "yes", "no", "yes", "no", "yes", "no", "yes"),
            feature_f = c("no", "no", "yes", "yes", "no", "no", "yes", "yes", "no", "no"))

   contract_id feature_a      feature_b      feature_c      feature_d feature_e feature_f
         <dbl> <chr>          <chr>          <chr>          <chr>     <chr>     <chr>    
         1001 yes            yes, mandatory no             yes       no        no       
         1002 no             no             yes, mandatory no        yes       no       
         1003 yes, mandatory yes            yes            yes       no        yes      
         1004 yes            yes, mandatory no             no        yes       yes      
         1005 no             no             yes, mandatory yes       no        no       
         1006 yes, mandatory yes            yes            no        yes       no       
         1007 yes            yes, mandatory no             yes       no        yes      
         1008 no             no             yes, mandatory no        yes       yes      
         1009 yes, mandatory yes            yes            yes       no        no       
         1010 yes            yes, mandatory no             no        yes       no 

我当然可以为每一列创建一个连接,但这并不令人满意。我希望尽可能少地加入连接数:

df %>% 
      left_join(lookup_a, by = c("feature_a" = "id")) %>% 
      select(-feature_a) %>% 
      rename(feature_a = value)

我也尝试过使用 data.table 或 match 的不同方法,但我还没有找到一次连接多个列的方法。我的问题是所有列都更改了,而不是选定的列。

这是我的问题:

  • 有没有办法一次对多个列(例如 left_join)进行连接/匹配,并使用列的名称进行重命名?
  • 或者是否可以一次替换多个列的值?

也许我现在想的太复杂了,解决的方法比较简单。

提前谢谢你!

【问题讨论】:

  • 您应该阅读 r 中的因子。它们的功能类似于 SAS 中的格式。
  • 嗨@Jim,您的意思是stringasfactors = yes 还是稍后定义因素?

标签: r join data-manipulation


【解决方案1】:

欢迎!您可以在 mutate 动词中使用您要更改的列索引使用 across 替换多个列的值(a 到 c 列为 2 到 4,d 到 f 列为 5 到 7):

library(dplyr)
df %>% 
  mutate(across(2:4,
         ~case_when(. == 1 ~ "Yes",
                    . == 2 ~ "No",
                    . == 3 ~ "Yes, mandatory",
                    TRUE ~ "Error"))) %>%
  mutate(across(5:7,
                ~case_when(. == 1 ~ "Yes",
                           . == 2 ~ "No",
                           TRUE ~ "Error")))

输出:

# A tibble: 10 x 7
   contract_id feature_a      feature_b      feature_c      feature_d feature_e feature_f
         <dbl> <chr>          <chr>          <chr>          <chr>     <chr>     <chr>    
 1        1001 Yes            Yes, mandatory No             Yes       No        No       
 2        1002 No             No             Yes, mandatory No        Yes       No       
 3        1003 Yes, mandatory Yes            Yes            Yes       No        Yes      
 4        1004 Yes            Yes, mandatory No             No        Yes       Yes      
 5        1005 No             No             Yes, mandatory Yes       No        No       
 6        1006 Yes, mandatory Yes            Yes            No        Yes       No       
 7        1007 Yes            Yes, mandatory No             Yes       No        Yes      
 8        1008 No             No             Yes, mandatory No        Yes       Yes      
 9        1009 Yes, mandatory Yes            Yes            Yes       No        No       
10        1010 Yes            Yes, mandatory No             No        Yes       No   

【讨论】:

  • 我没有想到简单但很好的解决方案真是太尴尬了。 @MonJeanJean 非常感谢!!我目前没有足够的声望来投票
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 2017-10-23
  • 1970-01-01
相关资源
最近更新 更多