Darren Tsai
Darren Tsai

Reputation: 35554

Function in outer() to identify exact equality

Please run this code:

list2env(list(df1 = iris, df2 = iris, df3 = CO2, df4 = CO2, df5 = cars), .GlobalEnv)

It will create 5 data.frame objects df1~df5 into your workspace.

Now I'm trying to identify which pair of objects is equal using identical() or all.equal(). First I pick up the object names:

name_df <- ls(pattern = "^df") # [1] "df1" "df2" "df3" "df4" "df5"

And the expected output is a table like this:

#       df1    df2    df3    df4    df5
# df1   TRUE   TRUE   FALSE  FALSE  FALSE
# df2   TRUE   TRUE   FALSE  FALSE  FALSE
# df3   FALSE  FALSE  TRUE   TRUE   FALSE
# df4   FALSE  FALSE  TRUE   TRUE   FALSE
# df5   FALSE  FALSE  FALSE  FALSE  TRUE 

But actually, I think I don't need to use tidyverse. The base function outer() might be more suitable in this case. However, the following code always gets an error no matter how I revise it.(I have tried Vectorize() each argument of identical() but it still doesn't work)

outer(name_df, name_df, function(x, y){
  identical(get(x), get(y))
# Vectorize(identical)(get(x), get(y))
})

Thanks for help!

Upvotes: 1

Views: 72

Answers (1)

akrun
akrun

Reputation: 887168

We can wrap with Vectorize on the function

f1 <- Vectorize(function(x, y) identical(get(x), get(y)))
outer(name_df, name_df, f1)
#     [,1]  [,2]  [,3]  [,4]  [,5]
#[1,]  TRUE  TRUE FALSE FALSE FALSE
#[2,]  TRUE  TRUE FALSE FALSE FALSE
#[3,] FALSE FALSE  TRUE  TRUE FALSE
#[4,] FALSE FALSE  TRUE  TRUE FALSE
#[5,] FALSE FALSE FALSE FALSE  TRUE

Or using tidyverse with crossing

library(tidyverse)
crossing(name_df, name_df) %>% 
   mutate(Equal = map2_lgl(mget(name_df, envir = .GlobalEnv), 
                          mget(name_df1, envir = .GlobalEnv), 
             identical)) %>% 
   spread(name_df1, Equal) %>%
   column_to_rownames('name_df')

Upvotes: 2

Related Questions