Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Can I Confirm that Two R objects have the same structure?

My test below doesn't work. Can anyone suggest a different approach?

===different contents, same structure, want "true" for comparison

> x<-c(1,2,3)
> y<-x
> identical(str(x),str(y))
 num [1:3] 1 2 3
 num [1:3] 1 2 3
[1] TRUE
> y[3]<-999
> identical(str(x),str(y))
 num [1:3] 1 2 3
 num [1:3] 1 2 999
[1] TRUE
> str(x)
 num [1:3] 1 2 3
> str(y)
 num [1:3] 1 2 999
> 

but this approach is wrong because this says x and z have the same structure!

> z<-list("a","b")
> identical(str(x),str(z))
 num [1:3] 1 2 3
List of 2
 $ : chr "a"
 $ : chr "b"
[1] TRUE

I'm trying this because I need a way to confirm that an R object I construct has exactly the same type as what is provided in R package examples.

like image 690
rwinkel2000 Avatar asked Sep 01 '25 02:09

rwinkel2000


1 Answers

Been a while since this question was asked, but I've been tackling a similar problem.

Came up with this function as a solution:

CompareStructure <-
  function(x, y) {
    # function to recursively compare a nested list of structure annotations
    # using pairwise comparisons
    TypeCompare <-
      function(xSTR, ySTR) {
        if (length(xSTR) == length(ySTR)) {
          all(mapply(
            xSTR,
            ySTR,
            FUN = function(xValue, yValue) {
              if (is.list(xValue) && is.list(yValue)) {
                all(TypeCompare(xValue, yValue))
              } else if (is.list(xValue) == is.list(yValue)) {
                identical(xValue, yValue)
              } else {
                FALSE
              }
            }
          ))
        } else {
          FALSE
        }
      }

    # if both inputs are lists
    if (is.list(x) && is.list(y)) {
      # use Rapply to recursively apply function down list
      xSTR <-
        rapply(
          x,
          f = function(values) {
            c(mode(values), length(values))
          },
          how = "list"
        )

      # use Rapply to recursively apply function down list
      ySTR <-
        rapply(
          y,
          f = function(values) {
            c(mode(values), length(values))
          },
          how = "list"
        )

      # call the compare function on both structure annotations
      return(TypeCompare(xSTR, ySTR))

    } else {
      # if inputs are not same class == automatic not same structure
      if (class(x) != class(y)) {
        FALSE
      } else {
        # get dimensions of the x input, if null get length
        xSTR <-
          if (is.null((dimsX <- dim(x)))) {
            length(x)
          } else {
            dimsX
          }

        # get dimensions of the y input, if null get length
        ySTR <-
          if (is.null((dimsY <- dim(y)))) {
            length(y)
          } else {
            dimsY
          }

        # call the compare function on both structure annotations
        return(TypeCompare(xSTR, ySTR))
      }
    }
  }

Compares the mode and length of elements in a nested list and classes and dimensions of no-list objects

like image 88
Danny Avatar answered Sep 02 '25 15:09

Danny