次の関数ペアはまったく同じ結果を生成しますか?
ペア1)names()
&colnames()
ペア2)rownames()
&row.names()
オスカー・ワイルドが言ったように
一貫性は想像を絶するものの最後の避難所です。
Rは、設計言語というよりも進化した言語であるため、これらのことが起こります。 names()
およびcolnames()
は_data.frame
_で機能しますが、names()
はマトリックスでは機能しません。
_R> DF <- data.frame(foo=1:3, bar=LETTERS[1:3])
R> names(DF)
[1] "foo" "bar"
R> colnames(DF)
[1] "foo" "bar"
R> M <- matrix(1:9, ncol=3, dimnames=list(1:3, c("alpha","beta","gamma")))
R> names(M)
NULL
R> colnames(M)
[1] "alpha" "beta" "gamma"
R>
_
Dirkの例を少し拡張するだけです。
データフレームを同じ長さのベクトルを持つリストと考えると役立ちます。それがおそらくnames
がデータフレームでは機能するが、マトリックスでは機能しない理由です。
他の便利な関数は、すべての次元の名前を返すdimnames
です。 rownames
関数は、実際にはdimnames
から最初の要素を返すだけであることに気付くでしょう。
rownames
およびrow.names
:rownames
はdimnames
を使用しますが、row.names
はRの外部で作成されました。どちらも高次元の配列で動作するようです:
>a <- array(1:5, 1:4)
> a[1,,,]
> rownames(a) <- "a"
> row.names(a)
[1] "a"
> a
, , 1, 1
[,1] [,2]
a 1 2
> dimnames(a)
[[1]]
[1] "a"
[[2]]
NULL
[[3]]
NULL
[[4]]
NULL
colnames
とrownames
を使用するのが最も理にかなっていると思います。その理由は次のとおりです。
names
を使用すると、いくつかの欠点があります。これは「列名」を意味し、データフレームでのみ機能することを覚えておく必要があります。そのため、行列を使用するときは常にcolnames
を呼び出す必要があります。 colnames
を呼び出すことで、1つの関数を覚えるだけで済みます。最後に、colnames
のコードを見ると、とにかくデータフレームの場合にnames
を呼び出すので、出力は同じです。
rownames
およびrow.names
は、データフレームとマトリックスに同じ値を返します。私が見つけた唯一の違いは、名前がない場合、rownames
が「NULL」を出力することです(colnames
と同様)が、row.names
は目に見えない形で返します。 2つの関数を選択することはあまりないので、rownames
は、colnames
とよりきれいにペアになるため、美学の理由で勝ちます。 (また、怠zyなプログラマーの場合は、入力する文字を保存します。)
そして別の拡張:
_# create dummy matrix
set.seed(10)
m <- matrix(round(runif(25, 1, 5)), 5)
d <- as.data.frame(m)
_
新しい列名を割り当てる場合は、_data.frame
_で次の操作を実行できます。
_# an identical effect can be achieved with colnames()
names(d) <- LETTERS[1:5]
> d
A B C D E
1 3 2 4 3 4
2 2 2 3 1 3
3 3 2 1 2 4
4 4 3 3 3 2
5 1 3 2 4 3
_
ただし、matrix
で前のコマンドを実行すると、混乱してしまいます。
_names(m) <- LETTERS[1:5]
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 3 2 4 3 4
[2,] 2 2 3 1 3
[3,] 3 2 1 2 4
[4,] 4 3 3 3 2
[5,] 1 3 2 4 3
attr(,"names")
[1] "A" "B" "C" "D" "E" NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[20] NA NA NA NA NA NA
_
マトリックスは2次元のベクトルと見なすことができるため、最初の5つの値にのみ名前を割り当てます(これはしたくないですか?)。この場合、colnames()
に固執する必要があります。
それで...