Noem meerdere kolommen op naam

Iemand had dit al moeten vragen, maar ik kon geen antwoord vinden. Zeg dat ik:

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

Wat is de meest elegante manier om een ​​willekeurige subset van kolommen te hernoemen, wiens positie ik niet noodzakelijk weet, in enkele andere willekeurige namen?

b.g. Stel dat ik wil hernoemen "q"en "e"in "A"EN "B", wat is de meest elegante code om dit te doen?

Uiteraard kan ik een lus doen:

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

Maar ik vraag me af of er een betere manier is? Misschien met behulp van enkele van de pakketten? (plyr::renameETC.)


1, Autoriteit 100%

setnamesVanaf de data.tablePakket werkt op data.frames of 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

Merk op dat wijzigingen worden aangebracht door verwijzing, dus geen kopiëren (zelfs voor gegevens.frames!)


2, Autoriteit 96%

Met DLYR zou u doen:

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

of als u vectoren wilt gebruiken, zoals gesuggereerd door @ 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. Nicolas Maystelde een wijziging voor aangezien rename_atwordt vervangen door rename_with:

df %>% 
  rename_with(~ newnames[which(oldnames == .x)], .cols = oldnames)
#  A w B
#1 1 2 3

Antwoord 3, autoriteit 37%

Een andere oplossing voor dataframes die niet te groot zijn is (voortbouwend op @thelatemail antwoord):

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

U kunt ook het volgende gebruiken:

names(x) <- c("C","w","D")
> x
  C w D
1 1 2 3

Bovendien kunt u ook een subset van de kolomnamen hernoemen:

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

Antwoord 4, autoriteit 22%

Dit is de meest efficiënte manier die ik heb gevonden om meerdere kolommen te hernoemen met een combinatie van purrr::set_names()en een paar stringr-bewerkingen.

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

Antwoord 5, autoriteit 11%

Dus ik kwam dit onlangs zelf tegen, als je niet zeker weet of de kolommen bestaan en alleen de kolommen wilt hernoemen die dat wel doen:

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

Antwoord 6, autoriteit 5%

Voortbouwend op het antwoord van @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

Dit is niet afhankelijk van een specifieke volgorde van kolommen in de xdataset.


Antwoord 7, autoriteit 4%

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

Antwoord 8, autoriteit 4%

Dit zou alle voorkomen van die letters in alle namen veranderen:

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

Antwoord 9, autoriteit 2%

U kunt de naam instellen, deze opslaan als een lijst en vervolgens uw bulk hernoemen op de tekenreeks. Een goed voorbeeld hiervan is wanneer u een lange naar brede overgang maakt op een dataset:

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" " 

Antwoord 10, autoriteit 2%

Opmerking: als u één tekenreeks wilt samenvoegen met alle kolomnamen, kunt u deze eenvoudige code gebruiken.

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

Antwoord 11, autoriteit 2%

Als de tabel twee kolommen met dezelfde naam bevat, gaat de code als volgt:

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

Antwoord 12, autoriteit 2%

U kunt een benoemde vector gebruiken.

Met grondtal R (misschien wat onhandig):

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

Of een dplyroptie met !!!:

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

Dit laatste werkt omdat de ‘big-bang’operator !!!de evaluatie van een lijst of een vector afdwingt.

?`!!`

!!! krachten-splice een lijst met objecten. De elementen van de lijst zijn:
op hun plaats gesplitst, wat betekent dat ze elk één enkel argument worden.


Antwoord 13, autoriteit 2%

Dplyr 1.0.0 bijwerken

De nieuwste dplyr-versie werd flexibeler door rename_with()toe te voegen waarbij _with verwijst naar een functie als invoer. De trucis om de tekenvector newnameste herformuleren in een formule (door ~), zodat deze gelijk is aan function(x) return (newnames).

Naar mijn subjectieve mening is dat de meest elegante dplyr-uitdrukking.

# shortest & most elegant expression
df %>% rename_with(~ newnames, oldnames)
A w B
1 1 2 3

Kanttekening:

Als u de volgorde omkeert, moet argument .fn worden opgegeven omdat .fn wordt verwacht vóór argument .cols.

df %>% rename_with(oldnames, .fn = ~ newnames)
A w B
1 1 2 3

Antwoord 14

Veel soorten antwoorden, dus ik heb de functie zojuist geschreven zodat je kunt kopiëren/plakken.

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

15

Als één rij van de gegevens de namen bevat die u wilt wijzigen die alle kolommen aan u kunnen wijzigen

names(data) <- data[row,]

Gegeven dataIs uw dataframe en rowhet rij-nummer met de nieuwe waarden.

Dan kunt u de rij verwijderen met de namen met

data <- data[-row,]

16

Dit is de functie die u nodig hebt:
Geef dan gewoon de x in een hernoemen (X) en het zal alle waarden hernoemen die verschijnen en als deze er niet in staat, zal het niet fout staan ​​

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

17

Veel goede antwoorden hierboven met behulp van gespecialiseerde pakketten. Dit is een eenvoudige manier om het alleen met BASE R te doen.

df.rename.cols <- function(df, col2.list) {
  tlist <- transpose(col2.list)
  names(df)[which(names(df) %in% tlist[[1]])] <- tlist[[2]]
  df
} 

Hier is een voorbeeld:

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

Other episodes