如何确认两个R对象具有相同的结构?

时间:2015-09-04 13:52:26

标签: r object compare structure

我的测试不起作用。任何人都可以提出不同的方法吗?

===不同的内容,相同的结构,想要“真实”进行比较

> 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
> 

但这种方法是错误的,因为这说x和z具有相同的结构!

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

我正在尝试这个,因为我需要一种方法来确认我构造的R对象与R包示例中提供的类型完全相同。

5 个答案:

答案 0 :(得分:1)

问这个问题已经有一段时间了,但我一直在解决类似的问题。

使用此功能作为解决方案:

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))
      }
    }
  }

比较嵌套列表中元素的模式和长度以及无列表对象的类和维度

答案 1 :(得分:0)

我正在回答a comment中提出的此问题的版本,即如何测试两个对象是否具有相同的类型,类,名称和其他属性,尽管可能是不同的数据。例如,您可能要确认两个矩阵具有相同的维,相同的行和列名称,并且具有相同的类型。

SameStruc <- function(x, y) identical(`is.na<-`(x), `is.na<-`(y))

我们可以在两个矩阵上对此进行测试:

M1 <- matrix(1:30, 3, 10, dimnames=list(LETTERS[1:3], letters[1:10]))
M2 <- M1
M2[1:30] <- 129:100
SameStruc(M1, M2)  # TRUE
                   # M1 and M2 are both integer matrices, 3 x 10, with the same dimnames but different data
M3 <- M1
M3[3,5] <- 1 * M3[3,5]
all(M1 == M3)      # TRUE  (the numerical values of the contents of M1 and M3 are the same)
SameStruc(M1, M3)  # FALSE (M3 has type "double" while M1 has type "integer")

我没有在列表或数据框或除矩阵外的任何对象上测试此功能。我认为它应该起作用,但前提是在列表上它只会测试最外层的列表结构,而不会测试每对列表元素的结构。

我还假定此功能对于大型对象而言效率非常低,因为它会为每个填充有NA的对象创建一个副本。

答案 2 :(得分:0)

我们现在在箭袋中有了一个新选项,它的名称为Waldo,可以更可靠地解决您的问题。但是,我仍然认为您可能希望编写自己的比较函数,以便了解发生了什么。

> library('waldo')
> x <- c(1,2,3)
> y <- x
> compare(x, y)
✓ No differences
> y[3] <- 999
> compare(x, y)
`old`: 1 2   3
`new`: 1 2 999

答案 3 :(得分:-1)

函数dput()用于结构。

x <- c(1, 2, 3)
y <- x
identical(dput(x), dput(y))
# c(1, 2, 3)
# c(1, 2, 3)
# [1] TRUE

z <- list("a", "b")
identical(dput(x), dput(z))
# c(1, 2, 3)
# list("a", "b")
# [1] FALSE

答案 4 :(得分:-1)

这个答案很晚,但可能会帮助面临同样问题的访问者。

  

我需要一种方法来确认我构造的R对象与[...]

具有完全相同的类型

对于这种特定情况,请考虑typeof()但是,这可能不是您想要的。

要检查data.frame中的矢量类型是否匹配,请查看sapply(df, typeof)

对于更通用的解决方案,我建议您自己构建检查,因为对于每个用例,“结构”可能具有不同的含义。它只是关于类型?您想区分doubleinteger吗?或者检查data.frame的名称?还是它的尺寸?如果除了一个因素的水平之外一切都相同怎么办?

自己构建它有一个很大的优势:你知道发生了什么。

其他有用的功能包括dim()ncol()nrow()names()class()attributes()mode()。< / p>