Каждый раз, когда id1 находится внутри строки в id3, поместите часть id2 в новый столбец - PullRequest
1 голос
/ 20 января 2020

Я хотел бы создать один дополнительный столбец для этого фрейма данных с некоторой дополнительной информацией: каждый раз, когда id1 находится внутри строки в id3, заменяйте эту часть его аналогом в id2:

 library(tidyverse)



    df1 <- tibble(
         id1 = c("119930", "124659", "114679", "119934", "126821", "124679", "119842", "134863", "133678", "133675"),
         id2 = c("AB1", "AB2", "AB3", "AB5", "AB4", "AB0", "DF1", "FR3", "GTA5", "BA1"),
         id3 = c("", "119934;126821;124679", "", "", "", "119842",  "", "", "", "133678;119930"))

Это что у меня есть:

    > df1
# A tibble: 10 x 3
   id1    id2   id3                   
   <chr>  <chr> <chr>                 
 1 119930 AB1   ""                    
 2 124659 AB2   "119934;126821;124679"
 3 114679 AB3   ""                    
 4 119934 AB5   ""                    
 5 126821 AB4   ""                    
 6 124679 AB0   "119842"       
 7 119842 DF1   ""                    
 8 134863 FR3   ""                    
 9 133678 GTA5  ""                    
10 133675 BA1   "133678;119930" 

Результат мне нужен:

    > df1
# A tibble: 10 x 4
   id1    id2   id3                    id4  
   <chr>  <chr> <chr>                  <chr>
 1 119930 AB1   ""                     ""   
 2 124659 AB2   "119934;126821;124679" "AB5;AB4;AB0"   
 3 114679 AB3   ""                     ""   
 4 119934 AB5   ""                     ""   
 5 126821 AB4   ""                     ""   
 6 124679 AB0   ""                     ""   
 7 119842 DF1   ""                     ""   
 8 134863 FR3   "119842"              "DF1"   
 9 133678 GTA5  ""                     ""   
10 133675 BA1   "133678;119930"               "GTA5;AB1"  

Ответы [ 3 ]

2 голосов
/ 20 января 2020

Один вариант, включающий stringr, может быть:

with(df1, str_replace_all(id3, setNames(id2, id1)))

 [1] ""            "AB5;AB4;AB0" ""            ""            ""            "DF1"        
 [7] ""            ""            ""            "GTA5;AB1"   
0 голосов
/ 20 января 2020

Основываясь на ответе @tmfmnk, полное решение будет выглядеть так:

    > df1 %>% mutate(id4 = str_replace_all(id3, setNames(id2, id1)))
# A tibble: 10 x 4
   id1    id2   id3                    id4          
   <chr>  <chr> <chr>                  <chr>        
 1 119930 AB1   ""                     ""           
 2 124659 AB2   "119934;126821;124679" "AB5;AB4;AB0"
 3 114679 AB3   ""                     ""           
 4 119934 AB5   ""                     ""           
 5 126821 AB4   ""                     ""           
 6 124679 AB0   "119842;134863"        "DF1;FR3"    
 7 119842 DF1   ""                     ""           
 8 134863 FR3   ""                     ""           
 9 133678 GTA5  ""                     ""           
10 133675 BA1   "133678"               "GTA5"      
0 голосов
/ 20 января 2020

Вот базовое решение R с использованием strsplit() + match()

df1$id4 <- apply(df1, 1, function(v) {
  paste0(na.omit(df1$id2[match(unlist(strsplit(v["id3"],split = ";")),df1$id1)]),collapse = ";")
})

таким, что

> df1
# A tibble: 10 x 4
   id1    id2   id3                  id4         
   <chr>  <chr> <chr>                <chr>       
 1 119930 AB1   ""                   ""          
 2 124659 AB2   "119934;126821;1246~ "AB5;AB4;AB~
 3 114679 AB3   ""                   ""          
 4 119934 AB5   ""                   ""          
 5 126821 AB4   ""                   ""          
 6 124679 AB0   "119842"             "DF1"       
 7 119842 DF1   ""                   ""          
 8 134863 FR3   ""                   ""          
 9 133678 GTA5  ""                   ""          
10 133675 BA1   "133678;119930"      "GTA5;AB1" 
...