2012-09-17 16 views
4

我在R的all.equal函數中遇到了一些奇怪的行爲。基本上,我創建兩個相同的data.frames,然後調用all.equal函數(檢查數據和屬性)。可能的錯誤在R all.equal

代碼重現行爲如下:

var.a <- data.frame(cbind(as.integer(c(1,5,9)), as.integer(c(1,5,9)))) 
colnames(var.a) <- c("C1", "C2") 
rownames(var.a) <- c("1","5","9") 

var.b <- data.frame(matrix(NA, nrow = 10, ncol = 2)) 
var.b[, 1] <- 1:10 
var.b[, 2] <- 1:10 
colnames(var.b) <- c("C1", "C2") 
var.b <- var.b[seq(1, nrow(var.b), 4), ] 

all.equal(var.a, var.b) 

這是一個bug或我只是失去了一些東西?我做了一些all.equall函數的調試,看起來問題在於data.frames的rownames(一旦它們是一個字符而另一次是數字向量)。

[1]:將all.equall功能的響應 「屬性:<組分2:模式:字符,數字>」
[2]「屬性:<組分2:目標是字符,當前是 數字>」

然而,

的typeof(rownames(var.a))== typeof運算(rownames(var.b))

返回TRUE,這讓我感到困惑。

P.S:物體的結構似乎是相同的:

> str(var.a) 
'data.frame': 3 obs. of 2 variables: 
$ C1: int 1 5 9 
$ C2: int 1 5 9 
> str(var.b) 
'data.frame': 3 obs. of 2 variables: 
$ C1: int 1 5 9 
$ C2: int 1 5 9 

我將不勝感激,如果有人可以在此提供一些線索。

回答

11

(我不太清楚你在想什麼錯誤,你已經找到了數據幀未建立以同樣的方式。)有在var中的結構有兩點不同。 a和var.b:列中元素的模式:'var.a'中的numeric和'var.b'中的integer;和rownames模式:integer爲「var.a」和character在「var.b」:

> dput(var.b) 
structure(list(C1 = c(1L, 5L, 9L), C2 = c(1L, 5L, 9L)), .Names = c("C1", 
"C2"), row.names = c(1L, 5L, 9L), class = "data.frame") 
> dput(var.a) 
structure(list(C1 = c(1, 5, 9), C2 = c(1, 5, 9)), .Names = c("C1", 
"C2"), row.names = c("1", "5", "9"), class = "data.frame") 

> mode(attr(var.b, "row.names")) 
[1] "numeric" 
> storage.mode(attr(var.b, "row.names")) 
[1] "integer" 
> mode(attr(var.a, "row.names")) 
[1] "character" 

補充說明:如果你想檢查你應該使用「check.attributes」數值相等切換:

> all.equal(var.a, var.b, check.attributes=FALSE) 
[1] TRUE 

如果你看看var.bdput,你可以看到rownames是數字:

> dput(var.b) 
structure(list(C1 = c(1L, 5L, 9L), C2 = c(1L, 5L, 9L)), .Names = c("C1", 
"C2"), row.names = c(1L, 5L, 9L), class = "data.frame") 
+2

+10 - 字符/整數變化對row.names的幫助非常明確。 – mnel

+0

就是這樣。謝謝。這個幫助很好地解釋了它,雖然它不是最直觀的。 – Igor

0

一個是模式數字,另一個是模式整數。你可以看到這一點:

str(var.a); str(var.b) 


> str(var.a); str(var.b) 
'data.frame': 3 obs. of 2 variables: 
$ C1: num 1 5 9 
$ C2: num 1 5 9 
'data.frame': 3 obs. of 2 variables: 
$ C1: int 1 5 9 
$ C2: int 1 5 9 
+0

這是真的,但它不是全部原因。平等失敗。我忘了在重現問題的同時使其更加清醒。它現在捆綁在原始問題中。 – Igor

1

然而,

的typeof(rownames(var.a))== typeof運算(rownames(var.b))

返回true,這混淆了我。

除了最投票的回答,請注意,屬性被存儲爲"character"var.a"numeric"var.b

> attr(var.a, "row.names") 
[1] "1" "5" "9" 
> attr(var.b, "row.names") 
[1] 1 5 9 

儘管rownames()功能將其產值強迫到"character"

> rownames(var.a) 
[1] "1" "5" "9" 
> rownames(var.b) 
[1] "1" "5" "9" 

這就是爲什麼你在上面的命令中得到TRUE。按照?rownames

對於數據幀,用於rownames值應的非重複的和非缺失的名稱的字符向量(這被執行),以及用於colnames的字符向量(優選地)獨特語法無效的名稱。在這兩種情況下,值都會被as.character強制設置,並且設置colnames會將行名轉換爲字符。

更恰當檢查是:

> typeof(attr(var.a, "row.names")) == typeof(attr(var.b, "row.names")) 
[1] FALSE 

此說,我相信,all.equal()消息是神祕的最好...