Menu

R で列名を変更する方法(names, colnames, dplyr rename)

R でデータフレームの列名を変更する: names() と colnames()、位置による変更と名前による変更、setNames()、dplyr の rename()、そして雑然としたインポート済みヘッダーの整理。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

まず名前を見る: names() と colnames()

列名は、どんなベクトルとも同じように読める属性の中にあります。データフレームに対しては names()colnames() もそれを返します。

答えは同じです。唯一の実質的な違いは、colnames() は行列でも動くが names() は動かないことです — そのため汎用的なコードは colnames() を使います。日常的なデータフレームでは交換可能です。

以下すべての鍵となる洞察はこれです。列名の変更とは、このベクトルへの代入である。 専用の base 関数はありません。どんなベクトルにも使うのと同じ添字付けで names(df) を書き換えるのです。

位置による変更(動くが脆い)

名前ベクトルを位置で添字付けして代入します。

2 列目が price になりました。対話的な素早い修正には十分ですが、スクリプトでは罠です。位置は列順についての約束であり、列順はインポートしたデータで最も不安定なものです。読み込む CSV に列が 1 つ増えた日、names(df)[2] は黙って別の列の名前を変えてしまいます。スクリプトが位置で名前を変更していると、スキーマの変更がエラーメッセージなしにそれを壊します。

名前による変更(堅牢な base の定型句)

位置を信じる代わりに、古い名前で照合します。

内側から読みましょう。names(sales) == "prc"FALSE TRUE FALSE を生みます — 名前ベクトルに対する論理マスクです。それで添字付けすると一致する項目が選ばれ、代入がそれを置き換えます。"prc" が存在しなければ何も一致せず、何も変わりません(エラーは出ないので、結果を確認しましょう)。この定型句は並べ替えにも、列の追加にも、他のスクリプトへのコピペにも耐えます。覚えてしまいましょう。これが「列名を変更する」ことに対する base R の答えです。

一度に複数

すべての列に名前を付けるとき(インポート直後によくあります)はベクトル全体を置き換え、選んだ一部を変更するには match() を使います。

match(old, names(df)) は古い名前の位置を返すので、新しい名前は古い名前があったちょうどその場所に収まります — 単一名の定型句と同じく順序に強い方法です。古い名前のどれかが見つからない場合、match()NA を返して代入がエラーになります。これは望ましい失敗の仕方です。大きな声で失敗します。

パイプライン向けの setNames()

上記の定型句はすべて 2 段階で変数を書き換えます。setNames(object, names) は 1 つの式で名前を変えた コピー を返し、これはパイプラインが求めるものです。

関数が名前のない、あるいは名前の悪いフレームを返したときに、一時変数なしでその場で直したい場合に便利です — read_something() |> setNames(c("id", "value")) のように。

dplyr のやり方: rename() と rename_with()

dplyr の rename()new = old の対を取ります — 新しい名前が で、誰もが一度は逆にします(静的な例です。サンドボックスは base R しか実行しません)。

library(dplyr)

sales |> rename(price = prc, qty = q)

呼び出しで触れられなかった古い名前はそのまま残り、古い名前の綴りを間違えると黙って何もしないのではなく明確なエラーになります — base の定型句に対する本物の改善です。対ではなく 規則 で名前を変えるには、rename_with() が名前に関数を適用します。

sales |> rename_with(toupper)                          # every column
sales |> rename_with(toupper, starts_with("p"))        # just some

これらが動詞ファミリーにどう収まるかは dplyr 入門 を参照してください。

雑然としたインポート済みヘッダーの整理

実際の CSV ヘッダーは "Order ID""unit.price ($)""2024 Total" のように届きます — 空白や記号を含む名前で、あちこちでバッククォートによる引用を強いられます。base R の make.names() は任意の文字列ベクトルを有効な R の名前に変換します。

有効ではありますが、これはこれで醜いです(X2024.Total)。だからこそ多くのチームは janitor パッケージの clean_names() に標準化します。1 回の呼び出しで整った snake_caseorder_id, unit_price, x2024_total)を生成します: df |> janitor::clean_names()。乱雑なファイルを毎週インポートしているなら、すぐに元が取れます。

この記事のまとめ

  • 列名は単なるベクトルです。names() / colnames() で読み、そこへ代入して名前を変えます。
  • names(df)[2] <- "new" は脆く、names(df)[names(df) == "old"] <- "new" が覚えるべき定型句です。
  • match() は名前で複数を変更し、setNames() はパイプラインの中でその場で変更します。
  • dplyr の rename(new = old) は存在しない名前でエラーになり(良いこと)、rename_with() は規則で変更します。
  • 乱雑なインポート済みヘッダーには、base では make.names()、きれいな結果には janitor::clean_names() を。

次は 並べ替え — ベクトルのための sort()、データフレームのための order() の技、そして arrange() です。

よくある質問

R で列名を変更するにはどうすればよいですか?

堅牢な base の定型句は名前で照合する方法です: names(df)[names(df) == "old"] <- "new"。old という名前の列がどこにあっても見つけて変更します。dplyr では rename(df, new = old) です — 順序に注意してください。新しい名前が先です。

names() と colnames() の違いは何ですか?

データフレームでは実質的にありません — どちらも列名を読み書きします。colnames() は行列でも動きます(names() は動きません)ので、両方を扱うコードでは colnames() が使われがちです。素のデータフレームでは好きな方を使ってください。

R で位置を指定して列名を変更するにはどうすればよいですか?

名前ベクトルのその位置に代入します: names(df)[2] <- "price" は 2 番目の列の名前を変更します。動きはしますが脆いです。列が追加されたり CSV の列順が変わったりした日には、位置 2 は別の列になります。名前による変更を優先しましょう。

R で複数の列名を一度に変更するにはどうすればよいですか?

ベクトル全体を代入します: names(df) <- c("id", "name", "price") は順にすべての名前を置き換えます。名前を指定していくつかだけ変更するには match() を使います: names(df)[match(c("old1", "old2"), names(df))] <- c("new1", "new2")。dplyr では rename(df, new1 = old1, new2 = old2) です。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める