根据尾随零模式将查找 table 中的值附加到另一个数据框的列

appending values from a look-up table to columns of another data frame based on trailing zero patterns

数据框 dat 在名为 code_num 的向量中包含一组数字 ID。其中一些 ID 以一个或多个零结尾。其他人没有。这是前三行:

code_num   X1   X2   X3   …   X50
251000     NA   NA   NA       NA        
112020     NA   NA   NA       NA        
537199     NA   NA   NA       NA

dat 的完整数据在 this google sheet 的第一个选项卡中。

另一个数据框 lut 包含另一组称为 code_num_moredetail 的数字 ID,需要与 dat 中的更高级别标识符相关联。以下是 lut:

的七个观察示例
code_num_moredetail
251000.99
251743.00
251222.02
112020.01
112029.01
537119.00
537119.99

lut 的完整数据在 this google sheet 的第二个选项卡中。

dat$code_num 中的尾随零是通配符数字。 lut$code_num_moredetail 的任何值与 dat$code_num 的尾随零之前的数字相匹配都应被视为匹配值,并且需要添加到 dat$X1dat$X50 的第 i 个值(或更多 - 我不确定会有多少场比赛)。

考虑两个示例案例:

  1. 如果 dat$code_num = 999000,则 lut$code_num_moredetail 的每个与模式 999###.## 匹配的值都需要插入到以字母 X 开头的列中在 dat.
  2. if dat$code_num = 999090 那么 lut$code_num_moredetail 的每个与模式 99909#.## 匹配的值都需要插入到以字母 X 开头的列中dat.

仅使用示例数据框中提供的值,最终解决方案将使 dat 看起来像这样:

code_num              X1          X2          X3
251000                251000.99   251743.00   251222.02
112020                112020.01   112029.01   NA
537199                537119.00   537119.99   NA

我正在寻找一种有效的方法来增加 dat 的所有通配符匹配值 lut

注意:dat$code_num 的某些值可能与 lut$code_num_moredetail 的任何值都不匹配 - 正确的解决方案必须包含 i 个匹配项,其中 i 的范围可以从 0 到 50。

尝试

library(dplyr)
library(tidyr)
library(data.table)
library(stringr)
out <- lut %>%
     mutate(new = substr(code_num_moredetail, 1, 3)) %>% 
     left_join(dat %>%
       transmute(code_num, new = substr(code_num, 1, 3)))  %>% 
    mutate(rn = str_c("X", rowid(new))) %>%
    pivot_wider(names_from = rn, values_from = code_num_moredetail) %>%
    select(-new)

-输出

out
# A tibble: 3 x 4
  code_num      X1      X2      X3
     <int>   <dbl>   <dbl>   <dbl>
1   251000 251001. 251743  251222.
2   112020 112020. 112029.     NA 
3   537199 537119  537120.     NA 

数字在数据中。这只是 tibble print

print(out$X3, digits = 10)
[1] 251222.02        NA        NA

或者可能是

library(fuzzyjoin)
dat1 <- dat %>%
         transmute(code_num, new = sub("0+$", "", code_num))

lut$new <- str_replace(sub("\..*", "", sprintf('%.2f', lut[[1]])), 
       paste0(".*(", paste(dat1$new, collapse="|"), ").*"), "\1")

stringdist_left_join(lut, dat1) %>% 
    select(code_num_moredetail, code_num, new = new.x) %>%
    mutate(rn = str_c("X", rowid(new))) %>%
    pivot_wider(names_from = rn, values_from = code_num_moredetail) %>%
    select(-new)

-输出

# A tibble: 3 x 4
  code_num      X1      X2      X3
     <int>   <dbl>   <dbl>   <dbl>
1   251000 251001. 251743  251222.
2   112020 112020. 112029.     NA 
3   537199 537119  537120.     NA 

数据

lut <- structure(list(code_num_moredetail = c(251000.99, 251743, 251222.02, 
112020.01, 112029.01, 537119, 537119.99)), row.names = c(NA, 
-7L), class = "data.frame")

dat <- structure(list(code_num = c(251000L, 112020L, 537199L), 
     X1 = c(NA, 
NA, NA), X2 = c(NA, NA, NA), X3 = c(NA, NA, NA)), class = "data.frame", 
   row.names = c(NA, 
-3L))