如何将几个变量的值与查找表中的变量进行匹配?

Emm*_*Nej 5 lookup r apply dplyr

我有两个数据集:

loc <- c("a","b","c","d","e")
id1 <- c(NA,9,3,4,5)
id2 <- c(2,3,7,5,6)
id3 <- c(2,NA,5,NA,7)
cost1 <- c(10,20,30,40,50)
cost2 <- c(50,20,30,30,50)
cost3 <- c(40,20,30,10,20)
dt <- data.frame(loc,id1,id2,id3,cost1,cost2,cost3)


id <- c(1,2,3,4,5,6,7)
rate <- c(0.9,0.8,0.7,0.6,0.5,0.4,0.3)
lookupd_tb <- data.frame(id,rate)
Run Code Online (Sandbox Code Playgroud)

我想要做的是将dt中的值与lookup_tb中的id1,id2和id3相匹配,如果匹配,则将该id乘以其相关成本.

这是我的方法:

dt <- dt %>% 
left_join(lookupd_tb , by=c("id1"="id")) %>%
dplyr :: mutate(cost1 = ifelse(!is.na(rate), cost1*rate, cost1)) %>% 
dplyr :: select (-rate)
Run Code Online (Sandbox Code Playgroud)

我现在正在做什么,工作正常,但我必须为每个变量重复3次,我想知道是否有更有效的方法来做到这一点(可能使用申请家庭?)

我尝试在我的查找表中加入所有三个带id的变量,但是当使用我的dt加速时,所有成本(cost1,cost2和cost3)将乘以我不想要的相同速率.

我感谢您的帮助!

akr*_*run 7

base R的方法将是循环通过的"id"使用的柱sapply/lapply,得到了match从"lookupd_tb",基于该索引的"id"列ING索引,得到相应的"速率",replaceNA带1的元件,具有乘' "成本"列并更新"费用"列

nmid <- grep("id", names(dt))
nmcost <- grep("cost", names(dt))

dt[nmcost] <- dt[nmcost]*sapply(dt[nmid], function(x) {
         x1 <- lookupd_tb$rate[match(x, lookupd_tb$id)]
          replace(x1, is.na(x1), 1) })
Run Code Online (Sandbox Code Playgroud)

或者使用tidyverse,我们可以循环遍历列的集合,即'id'和'cost' purrr::map2,然后执行与上面相同的方法.唯一的区别是,我们在这里创建了新列而不是更新"成本"列

library(tidyverse)
dt %>% 
   select(nmid) %>% 
   map2_df(., dt %>% 
               select(nmcost), ~  
                 .x %>% 
                     match(., lookupd_tb$id) %>%
                     lookupd_tb$rate[.] %>% 
                     replace(., is.na(.),1) * .y ) %>%
    rename_all(~ paste0("costnew", seq_along(.))) %>%
    bind_cols(dt, .)
Run Code Online (Sandbox Code Playgroud)