이름으로 여러 열 이름 바꾸기


84

누군가 이미이 질문을 했어야하는데 답을 찾을 수 없었습니다. 내가 가지고 있다고 :

x = data.frame(q=1,w=2,e=3, ...and many many columns...)  

위치를 알 수없는 임의의 열 하위 집합을 다른 임의의 이름으로 이름을 바꾸는 가장 우아한 방법은 무엇입니까?

예를 들어 말 나는 이름을 바꿀 "q""e""A"하고 "B",이 작업을 수행하는 가장 우아한 코드는 무엇인가?

분명히 루프를 수행 할 수 있습니다.

oldnames = c("q","e")
newnames = c("A","B")
for(i in 1:2) names(x)[names(x) == oldnames[i]] = newnames[i]

그러나 더 나은 방법이 있는지 궁금합니다. 패키지 중 일부를 사용하고 있습니까? ( plyr::rename등)

답변:


106

setnames로부터 data.table패키지에서 작동 data.frames 또는 data.tableS

library(data.table)
d <- data.frame(a=1:2,b=2:3,d=4:5)
setnames(d, old = c('a','d'), new = c('anew','dnew'))
d


 #   anew b dnew
 # 1    1 2    4
 # 2    2 3    5

변경은 참조에 의해 이루어 지므로 복사하지 마십시오 (data.frame에 대해서도!).


1
여기에 늦게 도착하는 경우-또한 모든 것이 표시되지 않을 수있는 이름 변경 목록이있는 경우 기존 열을 확인하는 아래 의 Joel의 답변을 살펴보십시오. 예old = c("a", "d", "e")
micstr

1
전체가 아닌 하위 집합 / 일부 열의 이름 만 변경하려는 경우에만 작동합니까? 따라서 10 개의 열로 구성된 데이터 프레임이 있고 _id_firstname을 firstname으로, _id_lastname을 lastname으로 이름을 바꾸고 싶지만 나머지 8 개 열은 그대로두고 싶은 경우이 작업을 수행하거나 모든 열을 나열해야합니까?
Mus

@MusTheDataGuy 새 이름과 이전 이름의 하위 집합을 제공하면 작동합니다.
mnel

@mnel @Mus가 요청한대로 하위 집합의 변수 이름을 변경해야합니다. 그러나 위의 코드는 데이터 하위 집합에 대해 작동하지 않았습니다. @Gorka의 대답 rename_at()은 하위 집합의 변수 이름을 변경하는 데 사용되었습니다.
Mehmet Yildirim

95

dplyr을 사용하면 다음을 수행 할 수 있습니다.

library(dplyr)

df = data.frame(q = 1, w = 2, e = 3)
    
df %>% rename(A = q, B = e)

#  A w B
#1 1 2 3

또는 @ Jelena-bioinf가 제안한대로 벡터를 사용하려는 경우 :

library(dplyr)

df = data.frame(q = 1, w = 2, e = 3)

oldnames = c("q","e")
newnames = c("A","B")

df %>% rename_at(vars(oldnames), ~ newnames)

#  A w B
#1 1 2 3

LD Nicolas May 는 주어진 변경 사항이 다음 rename_at으로 대체 될 것이라고 제안 했습니다 rename_with.

df %>% 
  rename_with(~ newnames[which(oldnames == .x)], .cols = oldnames)

#  A w B
#1 1 2 3

2
사용자가 통과에 대한 질문 oldnew벡터로 이름, 내 생각
JelenaČuklina

4
@ Jelena-bioinf에게 감사드립니다. 귀하의 제안을 포함하도록 답변을 수정했습니다.
Gorka

rename_with 예제에서 ~ (물결표)의 의미와 ".x"의 출처를 설명해 주시겠습니까?
petzi

rename_with함수 또는 수식을 사용하여 .cols인수 로 지정된 모든 열의 이름을 바꿀 수 있습니다 . 예를 들어 rename_with(iris, toupper, starts_with("Petal"))rename_with(iris, ~ toupper(.x), starts_with("Petal")).
Paul Rougieux

38

너무 크지 않은 데이터 프레임에 대한 또 다른 솔루션은 (@thelatemail 답변을 기반으로 작성) 다음과 같습니다.

x <- data.frame(q=1,w=2,e=3)

> x
  q w e
1 1 2 3

colnames(x) <- c("A","w","B")

> x
  A w B
1 1 2 3

또는 다음을 사용할 수도 있습니다.

names(x) <- c("C","w","D")

> x
  C w D
1 1 2 3

또한 열 이름의 하위 집합의 이름을 바꿀 수도 있습니다.

names(x)[2:3] <- c("E","F")

> x
  C E F
1 1 2 3

24

다음은 purrr::set_names()몇 가지 stringr작업 의 조합을 사용하여 여러 열의 이름을 바꾸는 가장 효율적인 방법 입니다.

library(tidyverse)

# Make a tibble with bad names
data <- tibble(
    `Bad NameS 1` = letters[1:10],
    `bAd NameS 2` = rnorm(10)
)

data 
# A tibble: 10 x 2
   `Bad NameS 1` `bAd NameS 2`
   <chr>                 <dbl>
 1 a                    -0.840
 2 b                    -1.56 
 3 c                    -0.625
 4 d                     0.506
 5 e                    -1.52 
 6 f                    -0.212
 7 g                    -1.50 
 8 h                    -1.53 
 9 i                     0.420
 10 j                     0.957

# Use purrr::set_names() with annonymous function of stringr operations
data %>%
    set_names(~ str_to_lower(.) %>%
                  str_replace_all(" ", "_") %>%
                  str_replace_all("bad", "good"))

# A tibble: 10 x 2
   good_names_1 good_names_2
   <chr>               <dbl>
 1 a                  -0.840
 2 b                  -1.56 
 3 c                  -0.625
 4 d                   0.506
 5 e                  -1.52 
 6 f                  -0.212
 7 g                  -1.50 
 8 h                  -1.53 
 9 i                   0.420
10 j                   0.957

6
이것이 답이되어야하지만 파이프 의 ~.인수가 set_names()수행하는 작업을 확장해야 할 수도 있습니다 .
DaveRGP

경우에 따라 명시 적으로를 입력해야합니다 purrr::set_names().
Levi Baguley

1
@DaveRGP purrr함수 를 사용할 때 물결표 ~는 "각 열"을 의미합니다. 은 .즉,이 경우에는 파이프 된 객체에 대한 참조 LHS = 파이프의 좌측 dplyr위한 구문이다 data.
Agile Bean

물결표 ~는 공식입니다. 또한 함수 호출을 사용하여에 인수를 전달할 수 ...의 인수 set_names예가 rlang::set_names(head(iris), paste0, "_hi")동일합니다 rlang::set_names(head(iris), ~ paste0(.x, "_hi")).
Paul Rougieux

11

그래서 최근에 열이 있는지 확실하지 않고 해당 열의 이름 만 바꾸고 싶다면 직접이 문제를 해결했습니다.

existing <- match(oldNames,names(x))
names(x)[na.omit(existing)] <- newNames[which(!is.na(existing))]

6

@ user3114046의 답변을 기반으로 작성 :

x <- data.frame(q=1,w=2,e=3)
x
#  q w e
#1 1 2 3

names(x)[match(oldnames,names(x))] <- newnames

x
#  A w B
#1 1 2 3

이는 x데이터 세트 의 특정 열 순서에 의존하지 않습니다 .


1
나는 당신의 대답을 upvoted했지만,이, 특히 방법을 수행하는 훨씬 더 우아한 방법이 있는지 나는 아직도 그 이름으로 이름 바꾸기, 대신의 위치가 궁금
qoheleth

@qoheleth-이름으로 이름이 바뀝니다! 여기에는 위치 벡터 인 입력이 없습니다 match. 당신이 할 최선은 아마도 @mnel의 setnames대답 일 것입니다.
thelatemail 2014 년

1
당신이 말했듯이 명시 적으로 위치 벡터를 지정할 필요 match는 없지만 여전히 위치 지향 명령 이기 때문에 여전히 위치별로 이름을 바꾸는 것 입니다. 이 정신에서 나는 @ user3114046의 응답 위치를 기반으로 생각했습니다 ( %in%명령이 사물을 처리 (또는 시도) 한다고 생각했습니다 ). 물론, 저수준 메커니즘으로 드릴 다운 할 때 모든 명령이 위치 지향적이라고 주장 할 수 있다고 생각합니다 ....하지만 그게 내 뜻은 아닙니다 ... data.table 대답은 훌륭합니다. name명령.
qoheleth 2014 년

4

이렇게하면 모든 이름에서 해당 문자의 모든 발생이 변경됩니다.

 names(x) <- gsub("q", "A", gsub("e", "B", names(x) ) )

2
두 번의 이름 변경 인스턴스를 지나면 이것이 특히 우아하다고 생각하지 않습니다.
thelatemail 2014 년

나는 gsubfn대답을 할만큼 충분하지 않다 . 아마도 G. Grothendieck이 올 것입니다. 그는 정규식 마이스터입니다.
IRTFM 2014 년

4
names(x)[names(x) %in% c("q","e")]<-c("A","B")

2
내가 말했듯이 열의 위치를 ​​반드시 알 필요는 없기 때문에 솔루션 은 i <j에 대해 이전 에 발생 oldnames하도록 정렬 된 경우에만 작동합니다 . oldnames[i]oldnames[j]
qoheleth 2014 년

2

이름 세트를 가져 와서 목록으로 저장 한 다음 문자열에서 대량 이름을 변경할 수 있습니다. 이에 대한 좋은 예는 데이터 세트에서 장기에서 전체로 전환하는 경우입니다.

names(labWide)
      Lab1    Lab10    Lab11    Lab12    Lab13    Lab14    Lab15    Lab16
1 35.75366 22.79493 30.32075 34.25637 30.66477 32.04059 24.46663 22.53063

nameVec <- names(labWide)
nameVec <- gsub("Lab","LabLat",nameVec)

names(labWide) <- nameVec
"LabLat1"  "LabLat10" "LabLat11" "LabLat12" "LabLat13" "LabLat14""LabLat15"    "LabLat16" " 

2

참고, 하나의 문자열을 모든 열 이름에 연결하려면이 간단한 코드를 사용하면됩니다.

colnames(df) <- paste("renamed_",colnames(df),sep="")

2

테이블에 이름이 같은 두 개의 열이 있으면 코드는 다음과 같습니다.

rename(df,newname=oldname.x,newname=oldname.y)

2

명명 된 벡터를 사용할 수 있습니다.

베이스 R을 사용하면 (어쩌면 다소 투박 할 수 있음) :

x = data.frame(q = 1, w = 2, e = 3) 

rename_vec <- c(q = "A", e = "B")

names(x) <- ifelse(is.na(rename_vec[names(x)]), names(x), rename_vec[names(x)])

x
#>   A w B
#> 1 1 2 3

또는 dplyr옵션 !!!:

library(dplyr)

rename_vec <- c(A = "q", B = "e") # the names are just the other way round than in the base R way!

x %>% rename(!!!rename_vec)
#>   A w B
#> 1 1 2 3

후자는 '빅뱅' 연산자 !!!가 목록이나 벡터의 평가를 강제 하기 때문에 작동합니다 .

?`!!`

!!! 개체 목록을 강제 연결합니다. 목록의 요소는 제자리에 연결되어 각 요소가 하나의 단일 인수가됩니다.


이것이 어떻게 작동하는지 이해하지 못합니다- !!!oldnames반환 c("A", "B")하지만 어떤 논리가 이것을 변환 합니까 c("A", "w", "B")?
Agile Bean

@AgileBean 나는 !!! oldnames가 벡터를 반환한다는 것을 어디서 발견했는지 모르겠습니다. dplyr에서 여러 인수의 비표준 평가를 강제하는 데 사용됩니다. 참조하십시오 ?`!!` Use `!!!` to add multiple arguments to a function. Its argument should evaluate to a list or vector: args <- list(1:3, na.rm = TRUE) ; quo(mean(!!!args)). 이 설명을 대답에 추가 할 것 같습니다. 그것을 제기하기위한 건배
tjebo

1

많은 종류의 답변이 있으므로 복사 / 붙여 넣기 할 수 있도록 함수를 작성했습니다.

rename <- function(x, old_names, new_names) {
    stopifnot(length(old_names) == length(new_names))
    # pull out the names that are actually in x
    old_nms <- old_names[old_names %in% names(x)]
    new_nms <- new_names[old_names %in% names(x)]

    # call out the column names that don't exist
    not_nms <- setdiff(old_names, old_nms)
    if(length(not_nms) > 0) {
        msg <- paste(paste(not_nms, collapse = ", "), 
            "are not columns in the dataframe, so won't be renamed.")
        warning(msg)
    }

    # rename
    names(x)[names(x) %in% old_nms] <- new_nms
    x
}

 x = data.frame(q = 1, w = 2, e = 3)
 rename(x, c("q", "e"), c("Q", "E"))

   Q w E
 1 1 2 3

rename(x, c("q", "e"), c("Q", "E"))더 이상 dplyr 이름 바꾸기에서 작동하지 않는 것 같습니까?
sindri_baldur

0

데이터의 한 행에 모든 열을 변경할 이름이 포함되어 있으면 수행 할 수 있습니다.

names(data) <- data[row,]

주어진 data데이터 프레임과 row새 값을 포함하는 행 번호입니다.

그런 다음 이름이 포함 된 행을 제거 할 수 있습니다.

data <- data[-row,]

0

이것이 필요한 함수입니다 : 그런 다음 rename (X)에 x를 전달하면 나타나는 모든 값의 이름을 바꾸고 거기에 없으면 오류가 발생하지 않습니다.

rename <-function(x){
  oldNames = c("a","b","c")
  newNames = c("d","e","f")
  existing <- match(oldNames,names(x))
  names(x)[na.omit(existing)] <- newNames[which(!is.na(existing))]
  return(x)
}

1
이것은 JoelKuiper의 대답 과 같은 것 같지만 기능으로 재구성되었습니다 .....
Jaap

0

기능 언급 할 몇 가지 답변이 있습니다 dplyr::rename_withrlang::set_names이미는. 그들은 분리되어 있습니다. 이 답변은 두 가지의 차이점과 함수 및 수식을 사용하여 열 이름을 바꾸는 방법을 보여줍니다.

rename_with로부터 dplyr패키지로 주어진 컬럼 이름을 선택하는 기능 또는 수식을 사용할 수 .cols인수. 예를 들어 함수 이름을 전달합니다 toupper.

library(dplyr)
rename_with(head(iris), toupper, starts_with("Petal"))

공식을 전달하는 것과 같습니다 ~ toupper(.x).

rename_with(head(iris), ~ toupper(.x), starts_with("Petal"))

모든 열의 이름을 바꿀 때 set_namesrlang 패키지에서 사용할 수도 있습니다 . 다른 예제를 만들기 위해 paste0이름 바꾸기 기능으로 사용하겠습니다 . pasteO2 개의 인수를 취하므로 함수 또는 공식을 사용하는지 여부에 따라 두 번째 인수를 전달하는 방법이 다릅니다.

rlang::set_names(head(iris), paste0, "_hi")
rlang::set_names(head(iris), ~ paste0(.x, "_hi"))

rename_with데이터 프레임을 첫 번째 인수로 .data, 함수를 두 번째 인수로 .fn, 모든 열을 세 번째 인수 .cols=everything()로, 함수 매개 변수를 네 번째 인수로 전달하여 동일한 결과를 얻을 수 있습니다 .... 또는 두 번째, 세 번째 및 네 번째 인수를 두 번째 인수로 지정된 수식에 배치 할 수 있습니다.

rename_with(head(iris), paste0, everything(), "_hi")
rename_with(head(iris), ~ paste0(.x, "_hi"))

rename_with데이터 프레임에서만 작동합니다. set_names더 일반적이며 벡터 이름 변경도 수행 할 수 있습니다.

rlang::set_names(1:4, c("a", "b", "c", "d"))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.