2015-09-04 116 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)) 
     } 
    } 
    } 

比較在嵌套列表元素和類和尺寸沒有列表的模式和長度對象

相關問題