rmatchingunordered

Matching unordered values in R


I'm working with a dataset with two columns that look something like this:

df <- data.frame(
  Row1 = c("1, 2", "2, 6, 4", "3, 1", "2, 1, 4", "3"),
  Row2 = c("2, 5", "2, 6", "1, 3", "1, 4, 2", "3, 2")
)
Row1 Row2
"1, 2" "2, 5"
"2, 6, 4" "2, 6"
"3, 1" "1, 3"
"2, 1, 4" "1, 4, 2"
"3 "3, 2"

I want to run a script that allows me to identify whether Row2 matches Row1. The need to have the same exact values, but they don't need to be in the same order. So given the above, I'd want a result that tells me the following:

Row1 Row2 Match
"1, 2" "2, 5" FALSE
"2, 6, 4" "2, 6" FALSE
"3, 1" "1, 3" TRUE
"2, 1, 4" "1, 4, 2" TRUE
"3" "3, 2" FALSE

I've tried using match() and compare() and haven't found success with either. Match() produces TRUE as long as all the elements of Row1 are found in Row2, but this isn't what I'm looking for. I need to produce TRUE only when Row2 has the same exact numbers as Row1 and only those numbers, irrespective of order. On the other hand, Compare() produces an error if I try to create a new column to identify matches. This is what I enter:

df$match <- compareIgnoreOrder(df$row1, df$row2)

I've also tried this way:

df$match <- compare(df$row1, df$row2, ignoreAll = TRUE)

Both methods yield the following error: "Input must be a vector, not a object." And at this point I'm stuck. I've searched high and low but can't find any solutions. Help would be much appreciated.


Solution

  • You're comparing sets, so a set operation like ?setequal makes sense to me:

    df <- data.frame(
      Row1 = c("1, 2", "2, 6, 4", "3, 1", "2, 1, 4", "3"),
      Row2 = c("2, 5", "2, 6", "1, 3", "1, 4, 2", "3, 2")
    )
    
    do.call(mapply, c(setequal, unname(lapply(df, strsplit, split=",\\s+"))))
    ##[1] FALSE FALSE  TRUE  TRUE FALSE
    

    Or in a potentially less confusing form but one extra line:

    spl <- lapply(df, strsplit, split=",\\s+")
    mapply(setequal, spl[[1]], spl[[2]])
    ##[1] FALSE FALSE  TRUE  TRUE FALSE