rdataframetextmatching

Matching words with more than two number of words in different data frame in r


I have two data frames DF1 and DF2 like this.

ID = c(1, 2, 3, 4) 
Issues = c('Issue1, Issue4', 'Issue2, Issue5, Issue6', 'Issue3, Issue4', 'Issue1, Issue5')
Location = c('x', 'y', 'z', 'w')
Customer = c('a', 'b', 'c', 'd')
DF1 = data.frame(ID, Issues, Location, Customer)

Root_Cause = c('R1', 'R2', 'R3', 'R4')
List_of_Issues = c('Issue1, Issue3, Issue5', 'Issue2, Issue1, Issue4', 'Issue6, Issue7', 'Issue5, Issue6')  
DF2 = data.frame(Root_Cause, List_of_Issues)

I want to compare both the data frames with "Issues" of DF1 and "List_of_Issues" of DF2 and if more than two words in "Issues" column is there in "List_of_Issues" column in DF2, then I want to populate subsequent "Root_Cause" from DF2. My resulting data frame should look like DF3.

ID = c(1, 2, 3, 4)
Issues = c('Issue1, Issue4', 'Issue2, Issue5, Issue6', 'Issue3, Issue4', 'Issue1, Issue5')
Location = c('x', 'y', 'z', 'w')
Customer = c('a', 'b', 'c', 'd')
Root_Cause = c('R2', 'R4', NA, 'R1')
DF3 = data.frame(ID, Issues, Location, Customer, Root_Cause)

Solution

  • Using data.table:

    EDIT: I have edited your sample data to account for multi-root cause eventualities. In this data, ID==1 corresponds to both R2 and R3.

    Data

    ID = c(1, 2, 3, 4) 
    Issues = c('Issue1, Issue4, Issue6, Issue7', 'Issue2, Issue5, Issue6', 'Issue3, Issue4', 'Issue1, Issue5')
    Location = c('x', 'y', 'z', 'w')
    Customer = c('a', 'b', 'c', 'd')
    DF1 = data.table(ID, Issues, Location, Customer)
    
    Root_Cause = c('R1', 'R2', 'R3', 'R4')
    List_of_Issues = c('Issue1, Issue3, Issue5', 'Issue2, Issue1, Issue4', 'Issue6, Issue7', 'Issue5, Issue6')  
    DF2 = data.table(Root_Cause, List_of_Issues)
    

    Code

    DF1[, Issues := strsplit(Issues, split = ', ')]
    DF2[, List_of_Issues := strsplit(List_of_Issues, split = ', ')]
    
    DF1[, RootCause := lapply(Issues, function(x){
    
      matchvec = sapply(DF2[, List_of_Issues], function(y) length(unlist(intersect(y, x))))
      ids = which(matchvec > 1)
      str = DF2[, paste(Root_Cause[ids], collapse = ', ')]
    
      ifelse(str == '', NA, str)
    
    })]
    

    Result

    > DF1
       ID                      Issues Location Customer RootCause
    1:  1 Issue1,Issue4,Issue6,Issue7        x        a    R2, R3
    2:  2        Issue2,Issue5,Issue6        y        b        R4
    3:  3               Issue3,Issue4        z        c        NA
    4:  4               Issue1,Issue5        w        d        R1