Menu

R에서 열 이름 바꾸는 방법 (names, colnames, dplyr rename)

R에서 데이터 프레임의 열 이름 바꾸기: names()와 colnames(), 위치 기준 vs 이름 기준 변경, setNames(), dplyr rename(), 그리고 지저분한 임포트 헤더 정리하기.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

먼저 이름을 확인하기: names()와 colnames()

열 이름은 다른 벡터처럼 읽을 수 있는 속성에 들어 있습니다. 데이터 프레임에서는 names()colnames() 둘 다 이를 반환합니다:

결과가 같습니다. 진짜 차이는 하나뿐입니다: colnames()는 행렬에서도 동작하지만 names()는 그렇지 않습니다 - 그래서 범용 코드는 colnames()를 씁니다. 일상적인 데이터 프레임에서는 서로 바꿔 써도 됩니다.

아래 내용 전체를 관통하는 핵심은 이것입니다: 열 이름을 바꾸는 것은 이 벡터에 값을 할당하는 것입니다. 전용 base 함수는 없습니다. 다른 벡터와 똑같은 인덱싱으로 names(df)를 수정하면 됩니다.

위치로 이름 바꾸기 (동작하지만 취약함)

이름 벡터를 위치로 인덱싱해 할당합니다:

이제 2번 열이 price입니다. 대화형으로 빠르게 고칠 때는 괜찮지만 스크립트에서는 함정입니다. 위치는 열 순서에 대한 약속이고, 열 순서는 임포트한 데이터에서 가장 불안정한 요소입니다. 읽어 들인 CSV에 열이 하나 더 생기는 날 names(df)[2]는 조용히 엉뚱한 열의 이름을 바꿉니다. 스크립트가 위치로 이름을 바꾸면 스키마 변경이 오류 메시지 없이 그것을 망가뜨립니다.

이름으로 이름 바꾸기 (견고한 base R 관용구)

위치를 믿는 대신 옛 이름을 매칭합니다:

안쪽부터 읽으세요: names(sales) == "prc"FALSE TRUE FALSE를 만듭니다 - 이름 벡터 위의 논리 마스크입니다. 이것으로 인덱싱하면 일치하는 항목이 선택되고, 할당이 그 값을 교체합니다. "prc"가 없다면 아무것도 매칭되지 않고 아무것도 바뀌지 않습니다(오류도 없으니 결과를 확인하세요). 이 관용구는 열 순서 변경, 열 추가, 다른 스크립트로의 복사·붙여넣기에도 견딥니다. 외워 두세요. "열 이름 바꾸기"에 대한 base R의 답입니다.

여러 개를 한 번에

모든 열의 이름을 붙일 때는(임포트 직후에 흔합니다) 벡터 전체를 교체하고, 일부만 바꿀 때는 match()를 사용합니다:

match(old, names(df))는 옛 이름들의 위치를 반환하므로 새 이름이 정확히 옛 이름 자리에 놓입니다 - 단일 이름 관용구처럼 순서에 안전합니다. 옛 이름 중 하나라도 없으면 match()NA를 반환하고 할당이 오류를 냅니다. 바로 우리가 원하는 실패 방식입니다: 시끄러운 실패죠.

파이프라인을 위한 setNames()

위의 관용구들은 모두 두 단계로 변수를 변형합니다. setNames(object, names)는 이름이 바뀐 사본 을 한 표현식으로 반환하는데, 파이프라인에 필요한 형태입니다:

어떤 함수가 이름이 없거나 잘못 붙은 데이터 프레임을 반환할 때 임시 변수 없이 그 자리에서 고치고 싶다면 유용합니다 - 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 R 관용구 대비 진짜 개선점입니다. 쌍이 아니라 규칙 으로 이름을 바꾸려면 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()를 표준으로 씁니다. 한 번의 호출로 깔끔한 snake_case(order_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 R의 make.names(), 예쁜 결과를 원하면 janitor::clean_names()를 쓰세요.

다음 주제: 정렬 - 벡터를 위한 sort(), 데이터 프레임을 위한 order() 기법, 그리고 arrange().

자주 묻는 질문

R에서 열 이름을 어떻게 바꾸나요?

가장 견고한 base R 관용구는 이름으로 매칭하는 것입니다: names(df)[names(df) == "old"] <- "new". old라는 열이 어디에 있든 찾아서 이름을 바꿉니다. dplyr에서는 rename(df, new = old)입니다 - 순서에 주의하세요. 새 이름이 먼저입니다.

names()와 colnames()의 차이는 무엇인가요?

데이터 프레임에서는 실질적인 차이가 없습니다 - 둘 다 열 이름을 읽고 설정합니다. colnames()는 행렬에서도 동작하지만(names()는 안 됩니다) 둘 다 처리해야 하는 코드는 보통 colnames()를 씁니다. 평범한 데이터 프레임에서는 취향대로 쓰면 됩니다.

R에서 위치로 열 이름을 바꾸려면 어떻게 하나요?

이름 벡터의 해당 위치에 할당합니다: names(df)[2] <- "price"는 두 번째 열의 이름을 바꿉니다. 동작하기는 하지만 취약합니다 - 열이 추가되거나 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로 코딩 배우기

시작하기