jamzsabb
jamzsabb

Reputation: 1154

Compare two tables and return list of mismatches

I'd like to be able to compare two tables and have R return a list of records and variables that don't match.

For example, with the following two tables

> df1
  id let num
1 1a   a   1
2 2b   b   2
3 3c   c   3
4 4d   d   4
5 5e   e   5
> df2
  id let num
1 1a   a   1
2 2b   b   2
3 3c   c   3
4 4d   e   4
5 5e   d   5

I would want a compare() function to return something like "id=4d, let" to let me know that the let variable in the record with id = 4d doesn't match.

I have seen the compare library in CRAN but it only returns TRUE or FALSE for the entire variable if there is a mismatch. Is there a library with a different compare function, or a way to do this manually?

Upvotes: 0

Views: 499

Answers (3)

G. Cocca
G. Cocca

Reputation: 2541

Something like:

df_diff <- list()

 for (i in 1:ncol(df1)) 
{
 df_diff[[i]] <- df1$id[df2[i] != df1[i]]
 names(df_diff)[i] <- names(df1)[i]
}

This should produce (hopefully :)) a list of character vectors (one for each variable). Each vector contains the IDs of df1 where the records of the two df don't match.

Upvotes: 0

Ven Yao
Ven Yao

Reputation: 3710

df1 <- read.table(text="
id let1 num1
1a   a   1
2b   b   2
3c   c   3
4d   d   4
5e   e   5", head=T, as.is=T)

df2 <- read.table(text="
id let2 num2
1a   a   1
2b   b   2
3c   c   3
4d   e   4
5e   d   5", head=T, as.is=T)

df <- merge(df1, df2, by="id")
df$let <- ifelse(df$let1 == df$let2, "equal", "not equal")
df$num <- ifelse(df$num1 == df$num2, "equal", "not equal")
df
#   id let1 num1 let2 num2       let   num
# 1 1a    a    1    a    1     equal equal
# 2 2b    b    2    b    2     equal equal
# 3 3c    c    3    c    3     equal equal
# 4 4d    d    4    e    4 not equal equal
# 5 5e    e    5    d    5 not equal equal

Upvotes: 2

daroczig
daroczig

Reputation: 28632

You mean something like which? Quick reproducible example:

> m1 <- m2 <- matrix(1:9, 3)
> diag(m1) <- 0
> which(m1 != m2, arr.ind = TRUE)
     row col
[1,]   1   1
[2,]   2   2
[3,]   3   3

Upvotes: 0

Related Questions