【问题标题】:Match a column values to a list of vector of codes and create a column indicating which vector it belongs to将列值与代码向量列表匹配,并创建一个列,指示它属于哪个向量
【发布时间】:2021-04-07 14:46:34
【问题描述】:

我有一个tibble,其中的代码需要与另一个包含代码的向量列表相匹配。因此,在tibble 中,将创建一个新列,指示代码属于哪个向量。

tibble:

library(tidyverse)
df <- tibble(id = 1:6, code = c("1502", "0223", "", "0380", "0421", "7958"))

> df
# A tibble: 6 x 2
     id code  
  <int> <chr> 
1     1 "1502"
2     2 "0223"
3     3 ""    
4     4 "0380"
5     5 "0421"
6     6 "7958"

代码向量列表示例:

code_list <- 
  list(
  "0" = "",
  "2" = c("0031", "0202", "0223", "0362", "0380", "0381", "03810", "03811", "03812", "03819", "0382", "0383", "03840", "03841", "03842", "03843", "03844", "03849", "0388", "0389", "0545", "449", "77181", "7907", "99591", "99592"),
  "5" = c("042", "0420", "0421", "0422", "0429", "0430", "0431", "0432", "0433", "0439", "0440", "0449", "07953", "27910", "27919", "79571", "7958","V08"),
  "12" = c("1500", "1501", "1502", "1503", "1504", "1505", "1508", "1509", "2301", "V1003"))

code_cat 列是我要查找的结果。代码“1502”属于code_list中的向量“12”,依此类推。如果 code_list 是数据框,我本可以使用 join 函数之一。但由于它是一个列表,我不知道如何进行。或者我们可以尝试将 code_list 转换为数据框。

要求的结果:

# A tibble: 6 x 3
     id code   code_cat
  <int> <chr>  <chr>   
1     1 "1502" 12      
2     2 "0223" 2       
3     3 ""     0       
4     4 "0380" 2       
5     5 "0421" 5       
6     6 "7958" 5 

【问题讨论】:

    标签: r


    【解决方案1】:

    这行得通吗:

    library(tidyr)
    library(dplyr)
    library(tibble)
    df %>% 
          left_join(enframe(code_list) %>% unnest(value), by = c('code' = 'value')) %>% 
          select(1,2,'code_cat' = name)
    # A tibble: 6 x 3
         id code   code_cat
      <int> <chr>  <chr>   
    1     1 "1502" 12      
    2     2 "0223" 2       
    3     3 ""     0       
    4     4 "0380" 2       
    5     5 "0421" 5       
    6     6 "7958" 5     
    

    【讨论】:

      【解决方案2】:

      这是一个基本的 R 解决方案。它首先构建一个匹配代码和代码列表成员的矩阵列表。然后获取列表的名称并创建新列。

      m <- lapply(seq_along(code_list), function(i){
        code <- which(df$code %in% code_list[[i]])
        cbind(code, name = i)
      })
      m <- do.call(rbind, m)
      m <- m[order(m[,1]),]
      df$code_cat <- names(code_list)[ m[, 2] ]
      
      df
      ## A tibble: 6 x 3
      #     id code   code_cat
      #  <int> <chr>  <chr>   
      #1     1 "1502" 12      
      #2     2 "0223" 2       
      #3     3 ""     0       
      #4     4 "0380" 2       
      #5     5 "0421" 5       
      #6     6 "7958" 5 
      
      rm(m)    # final clean up
      

      【讨论】:

        【解决方案3】:

        这是另一种方式

        df %>% 
          dplyr::mutate(
            code_cat = unlist(
              lapply(code, function(x) names(
                which(
                  sapply(code_list, function(y) any(y %in% x)))))))
        

        【讨论】:

          猜你喜欢
          • 2014-02-08
          • 2018-01-06
          • 1970-01-01
          • 1970-01-01
          • 2011-02-05
          • 1970-01-01
          • 2019-06-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多