按名称重命名多个列

问题描述 投票:54回答:14

有人应该已经问过这个,但我找不到答案。说我有:

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等)

r dataframe rename r-faq
14个回答
83
投票

来自setnamespackage的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.frames!)


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

1
投票

旁注,如果要将一个字符串连接到所有列名,可以使用这个简单的代码。

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

1
投票

如果表包含两个具有相同名称的列,则代码如下所示,

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

0
投票

如果一行数据包含要更改所有列的名称,则可以执行此操作

names(data) <- data[row,]

鉴于data是您的数据帧,row是包含新值的行号。

然后,您可以删除包含名称的行

data <- data[-row,]

0
投票

这是你需要的功能:然后只需在重命名(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)
}

56
投票

使用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

29
投票

另一个不太大的数据帧解决方案是(基于@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

11
投票

所以我最近遇到了这个问题,如果您不确定列是否存在并且只想重命名那些:

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

8
投票

这是我发现使用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

5
投票

建立在@ 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数据集中列的特定排序。


4
投票

这将改变所有名称中所有出现的字母:

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

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

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" " 
© www.soinside.com 2019 - 2024. All rights reserved.