4

Rのall.equal関数で奇妙な動作に直面しました。基本的に、2つの同じdata.frameを異なる方法で作成してから、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)

これはバグですか、それとも何かが足りないだけですか?all.equall関数のデバッグをかなり行いましたが、問題はdata.framesの行名にあるようです(1つは文字で、もう1つは数値ベクトルです)。all.equall関数の応答:

[1] "属性:<コンポーネント2:モード:文字、数値>"
[2] "属性:<コンポーネント2:ターゲットは文字、現在は数値>"

でも、

typeof(rownames(var.a))== typeof(rownames(var.b))

TRUEを返します。これは私を混乱させます。

PS:オブジェクトの構造は同じようです:

> 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

誰かがこれに光を当てることができれば幸いです。

4

3 に答える 3

12

(どのバグを見つけたと思っているのか正確にはわかりません。データフレームは同じ方法で作成されていません。)var.aとvar.bの構造には2つの違いがあります。列:numeric「var.a」およびinteger「var.b」; および行名のモード: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、行名が数値であることがわかります。

> 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")
于 2012-09-17T06:29:09.703 に答える
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

データフレームの場合、行名の値は重複していない名前と欠落していない名前の文字ベクトルである必要があり(これは強制されます)、列名の場合は(できれば)一意の構文的に有効な名前の文字ベクトルです。どちらの場合も、値はas.characterによって強制変換され、colnamesを設定すると、行名が文字に変換されます。

より適切なチェックは次のとおりです。

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

そうは言っても、all.equal()メッセージはせいぜい不可解だと思います...

于 2015-09-01T10:45:24.003 に答える
0

1つはモード数値で、もう1つはモード整数です。あなたはこれを見ることができます:

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
于 2012-09-17T05:26:36.387 に答える