2015-09-04 115 views
2

我下面的测试不起作用。任何人都可以提出不同的方法?如何确认两个R对象具有相同的结构?

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

> 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中包示例提供。

+4

'str'返回'NULL' (你看到的是简单的打印,没有返回),所以你总是比较两个相同的空值。只需使用'identical(x,y)' – Frank

+0

您正在比较str中的对象而不是元素本身... –

+2

问题措辞并不是最清楚的,但我将它看作询问如何测试两个对象是否具有即使其内容可能不同,也是一个相当困难的问题。 –

回答

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

,不幸的是,对于内容也!(1,2,3) c(1,2,3) c(1,2,3) c(1,2,3) c [1] TRUE > > Y [3] < - 999 >相同(dput(x)中,dput(Y)) C(1,2,3) C(1,2,999) [ 1] FALSE – rwinkel2000

-1

此答案相当晚,但可能有助于面对同一问题的访问者。

我需要一种方法,以确认的R对象我构造具有完全相同的类型为[...]

对于这个特定的情况下,考虑typeof()。但是,这可能不是你想要的。

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

对于更为一般的解决方案,我建议自己构建检查,因为对于每个用例,“结构”可以有不同的含义。它只是关于类型?您想区分doubleinteger吗?或者检查data.frame的名称?或其尺寸?如果除了一个因素的水平之外,一切都是相同的呢?自己构建它有一个很大的优势:你知道发生了什么。

其它有用的功能是dim()ncol()nrow()names()class()attributes()mode()

+0

'typeof'非常宽泛,对于这个问题几乎没有用处。例如,如果两个S3对象'A'和'B'都是具有class属性的列表,则'typeof(A)== typeof(B)==“list”' –

+0

例如:'typeof(lm(mpg〜。, mtcars))== typeof(rpart(mpg〜。,mtcars))' –

+0

这就是为什么我说:“但是,这可能不是你想要的。”请阅读我的答案的其余部分。 – sedot

0

过了一段时间,因为问了这个问题,但我一直在解决类似的问题。

想出了这个功能作为一个解决方案:

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

比较在嵌套列表元素和类和尺寸没有列表的模式和长度对象

相关问题