이름으로 여러 열 이름 바꾸기
누군가 이미 물어봤어야 했는데, 답을 찾을 수가 없었어요.내가 가지고 있다고 말하시오:
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
아래)
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
L. D. 니콜라스 메이는 주어진 변화를 제안했습니다.rename_at
에 의해 .rename_with
:
df %>%
rename_with(~ newnames[which(oldnames == .x)], .cols = oldnames)
# A w B
#1 1 2 3
setnames
data.table
는 패지작니다에서 할 것입니다.data.frame
상심한data.table
s
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.frames의 경우에도!).
너무 크지 않은 데이터 프레임을 위한 또 다른 솔루션은 다음과 같습니다(@latemail 응답 기반).
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
여러 열의 이름을 다음과 같이 조합하여 변경하는 가장 효율적인 방법은 다음과 같습니다.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
dplyr 1.0.0 업데이트
최신 dplyr 버전은 다음을 추가하여 더욱 유연해졌습니다.rename_with()
_with
함수를 입력이라고 합니다.요령은 문자 벡터를 재구성하는 것입니다.newnames
~
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , .function(x) return (newnames)
.
제 주관적인 생각으로는, 그것이 가장 우아한 dplyr 표현입니다.는 @desval: @desval로 묶어야 .all_of
모든 요소를 포함합니다.
# shortest & most elegant expression
df %>% rename_with(~ newnames, all_of(oldnames))
A w B
1 1 2 3
참고 사항:
순서를 반대로 할 경우 .fn 인수를 .cols 인수 앞에 .fn이 필요합니다.
df %>% rename_with(oldnames, .fn = ~ newnames)
A w B
1 1 2 3
또는 .col 인수를 지정합니다.
df %>% rename_with(.col = oldnames, ~ newnames)
A w B
1 1 2 3
그래서 최근에 열이 존재하는지 확실하지 않고 다음과 같은 이름만 변경하려는 경우 이 문제를 직접 경험했습니다.
existing <- match(oldNames,names(x))
names(x)[na.omit(existing)] <- newNames[which(!is.na(existing))]
@user314046의 답변을 기반으로 구축:
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
데이터 집합입니다.
명명된 벡터를 사용할 수 있습니다.두 가지 옵션(기본 R 및 dplyr 포함) 아래에 있습니다.
기본 R, 부분 집합을 통해:
x = data.frame(q = 1, w = 2, e = 3)
rename_vec <- c(q = "A", e = "B")
## vector of same length as names(x) which returns NA if there is no match to names(x)
which_rename <- rename_vec[names(x)]
## simple ifelse where names(x) will be renamed for every non-NA
names(x) <- ifelse(is.na(which_rename), names(x), which_rename)
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
후자는 '빅뱅' 연산자 때문에 작동합니다.!!!
목록 또는 벡터를 강제로 평가하는 것입니다.
?`!!`
개체 목록을 강제로 분할합니다.목록의 요소는 제자리에 결합되어 있으며, 이는 각 요소가 하나의 단일 인수가 된다는 것을 의미합니다.
names(x)[names(x) %in% c("q","e")]<-c("A","B")
기능을 언급하는 몇 가지 답변이 있습니다.dplyr::rename_with
그리고.rlang::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_names
랑그 패키지에서.예를 , 른다예들면자를,면들자를을 해 보겠습니다paste0
이름 바꾸기 기능으로 사용할 수 있습니다. pasteO
두 개의 인수를 사용하므로 함수를 사용하는지 공식을 사용하는지에 따라 두 번째 인수를 전달하는 방법이 달라집니다.
rlang::set_names(head(iris), paste0, "_hi")
rlang::set_names(head(iris), ~ paste0(.x, "_hi"))
다음과 같은 작업을 수행할 수 있습니다.rename_with
을 첫 인수로 으로써 첫 번 인 로 터 프 을 임 으 함 로 전 달 써 레 이 데 째 수 ▁by 첫 으 로 ▁the 함 써 ▁frame.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"))
이렇게 하면 모든 이름에 나타나는 모든 문자가 변경됩니다.
names(x) <- gsub("q", "A", gsub("e", "B", names(x) ) )
이름 집합을 가져와 목록으로 저장한 다음 문자열에서 대량 이름 변경을 수행할 수 있습니다.데이터셋을 전체적으로 길게 전환하는 경우를 예로 들 수 있습니다.
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" "
테이블에 이름이 같은 두 개의 열이 포함되어 있으면 코드는 다음과 같습니다.
rename(df,newname=oldname.x,newname=oldname.y)
참고로 문자열 하나를 모든 열 이름에 연결하려면 이 단순 코드를 사용하면 됩니다.
colnames(df) <- paste("renamed_",colnames(df),sep="")
롯은 일종의 답이기 때문에 복사/붙여넣기가 가능하도록 함수를 작성했습니다.
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
데이터의 한 행에 모든 열을 변경하려는 이름이 포함된 경우 다음과 같이 할 수 있습니다.
names(data) <- data[row,]
해진정data
이며 "데이터 프레임"입니다.row
새 값이 들어 있는 행 번호입니다.
그런 다음 이름이 포함된 행을 제거할 수 있습니다.
data <- data[-row,]
다음 기능이 필요합니다.그런 다음 이름 바꾸기(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)
}
전문 패키지를 사용하는 위의 많은 좋은 답변.이것은 기본 R로만 수행하는 간단한 방법입니다.
df.rename.cols <- function(df, col2.list) {
tlist <- transpose(col2.list)
names(df)[which(names(df) %in% tlist[[1]])] <- tlist[[2]]
df
}
다음은 예입니다.
df1 <- data.frame(A = c(1, 2), B = c(3, 4), C = c(5, 6), D = c(7, 8))
col.list <- list(c("A", "NewA"), c("C", "NewC"))
df.rename.cols(df1, col.list)
NewA B NewC D
1 1 3 5 7
2 2 4 6 8
저는 최근에 @agile bean의 답변으로 구축했습니다(사용).rename_with
의 전에종rename_at
)를사용하여 프레임에 하는 열 열시킬 수 있습니다 데이터 프레임에 열 이름이 있는 경우 이를 변경하는 함수를 구축하여, 해당하는 경우 이종 데이터 프레임의 열 이름을 서로 일치시킬 수 있습니다.
루프는 확실히 개선될 수 있지만, 저는 후손들을 위해 공유할 것이라고 생각했습니다.
예제 데이터 프레임 생성:
x= structure(list(observation_date = structure(c(18526L, 18784L,
17601L), class = c("IDate", "Date")), year = c(2020L, 2021L,
2018L)), sf_column = "geometry", agr = structure(c(id = NA_integer_,
common_name = NA_integer_, scientific_name = NA_integer_, observation_count = NA_integer_,
country = NA_integer_, country_code = NA_integer_, state = NA_integer_,
state_code = NA_integer_, county = NA_integer_, county_code = NA_integer_,
observation_date = NA_integer_, time_observations_started = NA_integer_,
observer_id = NA_integer_, sampling_event_identifier = NA_integer_,
protocol_type = NA_integer_, protocol_code = NA_integer_, duration_minutes = NA_integer_,
effort_distance_km = NA_integer_, effort_area_ha = NA_integer_,
number_observers = NA_integer_, all_species_reported = NA_integer_,
group_identifier = NA_integer_, year = NA_integer_, checklist_id = NA_integer_,
yday = NA_integer_), class = "factor", .Label = c("constant",
"aggregate", "identity")), row.names = c("3", "3.1", "3.2"), class = "data.frame")
기능.
match_col_names <- function(x){
col_names <- list(date = c("observation_date", "date"),
C = c("observation_count", "count","routetotal"),
yday = c("dayofyear"),
latitude = c("lat"),
longitude = c("lon","long")
)
for(i in seq_along(col_names)){
newname=names(col_names)[i]
oldnames=col_names[[i]]
toreplace = names(x)[which(names(x) %in% oldnames)]
x <- x %>%
rename_with(~newname, toreplace)
}
return(x)
}
기능을 적용합니다.
x <- match_col_names(x)
실행 시간을 위해 데이터 테이블 구조를 사용할 것을 제안합니다.
> df = data.table(x = 1:10, y = 3:12, z = 4:13)
> oldnames = c("x","y","z")
> newnames = c("X","Y","Z")
> library(microbenchmark)
> library(data.table)
> library(dplyr)
> microbenchmark(dplyr_1 = df %>% rename_at(vars(oldnames), ~ newnames) ,
+ dplyr_2 = df %>% rename(X=x,Y=y,Z=z) ,
+ data_tabl1= setnames(copy(df), old = c("x","y","z") , new = c("X","Y","Z")),
+ times = 100)
Unit: microseconds
expr min lq mean median uq max neval
dplyr_1 5760.3 6523.00 7092.538 6864.35 7210.45 17935.9 100
dplyr_2 2536.4 2788.40 3078.609 3010.65 3282.05 4689.8 100
data_tabl1 170.0 218.45 368.261 243.85 274.40 12351.7 100
사용하는 기본 방법setNames
그것을 []
첫 번째 시합을 할 것입니다.
names(x) <- setNames(c(newnames, names(x)), c(oldnames, names(x)))[names(x)]
names(x) <- (\(.) setNames(c(newnames, .), c(oldnames, .))[.])(names(x)) #Variant
x
# A w B
#1 1 2 3
용사를 합니다.transform
.
names(x) <- do.call(transform, c(list(as.list(setNames(names(x), names(x)))),
as.list(setNames(newnames, oldnames))))
데이터.
x = data.frame(q=1,w=2,e=3)
oldnames = c("q","e")
newnames = c("A","B")
언급URL : https://stackoverflow.com/questions/20987295/rename-multiple-columns-by-names
'source' 카테고리의 다른 글
Spring AppContext 없이 @ConfigurationProperties를 수동으로 로드할 수 있습니까? (0) | 2023.07.03 |
---|---|
ASP.Net MVC – 리소스를 찾을 수 없음 오류 (0) | 2023.06.28 |
경고: 'contexters'는 더 이상 사용되지 않습니다.문자열 또는 하위 문자열을 직접 사용하십시오. (0) | 2023.06.28 |
R data.frame에서 행을 가져오는 방법 (0) | 2023.06.28 |
VS 2010.net 4.0에서 엔티티 프레임워크를 사용할 때 'datetime2' 오류가 발생했습니다. (0) | 2023.06.28 |