Zmiana nazw kolumn ramki danych

399

Mam ramkę danych o nazwie „nowa cena” (patrz poniżej) i chcę zmienić nazwy kolumn w moim programie w języku R.

> newprice
   Chang.  Chang.   Chang.
1     100       36      136
2     120      -33       87
3     150       14      164

W rzeczywistości robię to:

names(newprice)[1]<-paste("premium")
names(newprice)[2]<-paste("change")
names(newprice)[3]<-paste("newprice") 

Nie umieściłem tego w pętli, ponieważ chcę, aby nazwa każdej kolumny była inna, jak widzisz.

Po wklejeniu mojego programu do konsoli R jest to dane wyjściowe:

> names(newprice)[1]<-paste(“premium”)
Error: unexpected input in "names(newprice)[1]<-paste(“"
> names(newprice)[2]<-paste(“change”)
Error: unexpected input in "names(newprice)[2]<-paste(“"
> names(newprice)[3]<-paste(“newpremium”)
Error: unexpected input in "names(newprice)[3]<-paste(“"

Próbowałem równie dobrze, c()na przykład c("premium"), zamiast paste()funkcji, ale bezskutecznie.

Czy ktoś mógłby mi pomóc to rozgryźć?

Syn
źródło
Jeśli odpowiedź Dirka działa, problem polega na tym, że pracujesz z matrycą, a nie z ramką danych. Możesz to sprawdzić za pomocą is.matrixlub str.
IRTFM
3
Zobacz tę odpowiedź na dplyr :: zmień nazwę stackoverflow.com/a/26146202/1831980
Rasmus Larsen
8
colnames(newprice)<- c("premium","change","newprice")
Tung Nguyen,
Twój błąd nie ma nic wspólnego z jakością twojego kodu. Po prostu używasz niewłaściwego symbolu. To „nie jest rozpoznawane przez R., zamiast tego użyj”. Wiem, że mogą wyglądać tak samo. Spójrz blisko: „”. Otóż ​​to.
Edo

Odpowiedzi:

593

Użyj colnames()funkcji:

R> X <- data.frame(bad=1:3, worse=rnorm(3))
R> X
  bad     worse
1   1 -2.440467
2   2  1.320113
3   3 -0.306639
R> colnames(X) <- c("good", "better")
R> X
  good    better
1    1 -2.440467
2    2  1.320113
3    3 -0.306639

Możesz także podzielić:

R> colnames(X)[2] <- "superduper"
Dirk Eddelbuettel
źródło
12
@Dirk Dlaczego nie używać names () zamiast colnames ()?
Antoine Lizée,
4
Świetny! Możesz także podgrupować wiele kolumn jednocześnie (przydatne w przypadku ramek z dużymi danymi). colnames(X)[c(1,2)] <- c("good", "better")
metakermit
7
Wypróbuj setnames()w data.tablepakiecie. Użyj czegoś takiego jak setnames(DT,"b","B")lubsetnames(DT,c("a","E"),c("A","F"))
dwstu
Dziwnie, po ustawieniu nazw kolumn ramki danych q1, próba zmutowania ramki danych za pomocą dplyras q1 <- q1 %>% mutate(rel_count = count / 482462)powoduje błąd Error in mutate_impl(.data, dots) : unknown column 'days'(gdzie daysnowa kolumna jest nadawana). To jest naprawdę frustrujące.
David Tonhofer,
176

Używam tego:

colnames(dataframe)[which(names(dataframe) == "columnName")] <- "newColumnName"
Matheus Abreu
źródło
7
Dziękuję Ci. Myślę, że jest to trochę denerwujące z R: Dlaczego tak trudno jest zmienić nazwę kolumny, jeśli nie chcesz używać numeru indeksu, ale stara nazwa :(
Arne
10
Zaletą tej metody jest to, że nie musisz martwić się o pozycję kolumny, o ile znasz jej oryginalną nazwę. Myślę, że jest to preferowana metoda, ponieważ możesz - później - wprowadzić zmiany w kodzie, które zmieniają pozycję kolumny, której nazwę chcesz zmienić.
Paulo S. Abreu,
78

Błąd jest spowodowany przez „inteligentne cytaty” (lub jakkolwiek się je nazywa). Lekcja brzmi: „nie pisz kodu w„ edytorze ”, który konwertuje cudzysłowy na inteligentne”.

names(newprice)[1]<-paste(“premium”)  # error
names(newprice)[1]<-paste("premium")  # works

Ponadto nie potrzebujesz paste("premium")(wezwanie do pastejest zbędne) i dobrym pomysłem jest umieszczenie spacji, <-aby uniknąć nieporozumień (np x <- -10; if(x<-3) "hi" else "bye"; x.).

Joshua Ulrich
źródło
51

Czy próbowałeś tylko:

names(newprice)[1]<-"premium"

?

Jamie
źródło
42

Nowym zalecanym sposobem na to jest użycie setNamesfunkcji. Zobaczyć ?setNames. Ponieważ tworzy to nową kopię data.frame, należy przypisać wynik do oryginału data.frame, jeśli taka jest Twoja intencja.

data_frame <- setNames(data_frame, c("premium","change","newprice"))

Nowsze wersje R ostrzegają, jeśli używasz colnamesniektórych sposobów sugerowanych przez wcześniejsze odpowiedzi.

Gdyby to był data.tablezamiast tego, można użyć data.tablefunkcji setnames, która może modyfikować określone nazwy kolumn lub nazwy pojedynczej kolumny przez odniesienie :

setnames(data_table, "old-name", "new-name")
Scott C. Wilson
źródło
2
myślę, że został poproszony o data.frame, a nie data.table
Helix123 16.04.15
35

Miałem ten sam problem i ten fragment kodu zadziałał dla mnie.

names(data)[names(data) == "oldVariableName"] <- "newVariableName"

W skrócie, ten kod wykonuje następujące czynności:

names(data)sprawdza wszystkie nazwy w dataframe ( data)

[names(data) == oldVariableName]wyodrębnia nazwę zmiennej ( oldVariableName), której nazwę chcesz zmienić, i <- "newVariableName"przypisuje nową nazwę zmiennej.

Desta Haileselassie Hagos
źródło
jak by to działało, gdybyś miał wektor z np. 3 oldVariableNames?
jiggunjer,
Dokładnie to, czego szukałem -> 2 kciuki do góry !!
SilSur
19

Podobne do innych:

cols <- c("premium","change","newprice")
colnames(dataframe) <- cols

Dość prosty i łatwy do modyfikacji.

Adam Erickson
źródło
10

próbować:

names(newprice) <- c("premium", "change", "newprice")
ngamita
źródło
10

Jeśli musisz zmienić nazwę nie wszystkich, ale wielu kolumn jednocześnie, gdy znasz tylko stare nazwy kolumn, możesz użyć colnamesfunkcji i %in%operatora. Przykład:

df = data.frame(bad=1:3, worse=rnorm(3), worst=LETTERS[1:3])

   bad      worse    worst
1   1 -0.77915455       A
2   2  0.06717385       B
3   3 -0.02827242       C

Teraz chcesz zmienić „zły” i „najgorszy” na „dobry” i „najlepszy”. Możesz użyć

colnames(df)[which(colnames(df) %in% c("bad","worst") )] <- c("good","best")

To skutkuje

  good      worse  best
1    1 -0.6010363    A
2    2  0.7336155    B
3    3  0.9435469    C
discipulus
źródło
1
Ten kod zakłada, że ​​kolejność nazw kolumn jest taka sama jak kolejność wstawek
Hillary Sanders
10

Użyj tego, aby zmienić nazwę kolumny według funkcji colname.

colnames(newprice)[1] = "premium"
colnames(newprice)[2] = "change"
colnames(newprice)[3] = "newprice"
Sophanna
źródło
8

Możesz po prostu dokonać edycji przez:

newprice <- edit(newprice)

i ręcznie zmień nazwę kolumny.

Baykal
źródło
Czy to nie działa tylko w przypadku elementów wektorowych i czynnikowych? > locanatmodelset<-edit(locanatmodelset) Error in edit.data.frame(locanatmodelset) : can only handle vector and factor elements
vagabond
Działa to przynajmniej w przypadku ramek danych. Właśnie to wiem.
Baykal
7

Moje nazwy kolumn są jak poniżej

colnames(t)
[1] "Class"    "Sex"      "Age"      "Survived" "Freq" 

Chcę zmienić nazwę kolumny Class and Sex

colnames(t)=c("STD","Gender","AGE","SURVIVED","FREQ")
Mehul Katara
źródło
7

Istnieje kilka opcji z dplyr::rename()i dplyr::select():

library(dplyr)

mtcars %>% 
  tibble::rownames_to_column('car_model') %>%                            # convert rowname to a column. tibble must be installed.
  select(car_model, est_mpg = mpg, horse_power = hp, everything()) %>%   # rename specific columns and reorder
  rename(weight = wt, cylinders = cyl) %>%                               # another option for renaming specific columns that keeps everything by default
  head(2)
      car_model est_mpg horse_power cylinders disp drat weight  qsec vs am gear carb
1     Mazda RX4      21         110         6  160  3.9  2.620 16.46  0  1    4    4
2 Mazda RX4 Wag      21         110         6  160  3.9  2.875 17.02  0  1    4    4

Istnieją również trzy warianty o zasięgu dplyr::rename(): dplyr::rename_all()dla wszystkich nazw kolumn, dplyr::rename_if()dla warunkowo kierowanych nazw kolumn i dplyr::rename_at()dla wybranych nazwanych kolumn. Poniższy przykład zastępuje spacje i kropki znakiem podkreślenia i konwertuje wszystko na małe litery:

iris %>%  
  rename_all(~gsub("\\s+|\\.", "_", .)) %>% 
  rename_all(tolower) %>% 
  head(2)
  sepal_length sepal_width petal_length petal_width species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa

dplyr::select_all() można również użyć w podobny sposób:

iris %>%  
  select_all(~gsub("\\s+|\\.", "_", .)) %>% 
  select_all(tolower) %>% 
  head(2)
  sepal_length sepal_width petal_length petal_width species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
sbha
źródło
6

Tylko w celu poprawienia i nieznacznego rozszerzenia odpowiedzi Scott Wilson.
Możesz także użyć setnamesfunkcji data.table w data.frames.

Nie należy oczekiwać przyspieszenia operacji, ale można oczekiwać, że setnamesbędzie ona bardziej wydajna pod względem zużycia pamięci, ponieważ aktualizuje nazwy kolumn przez odwołanie. Można to śledzić za pomocą addressfunkcji, patrz poniżej.

library(data.table)
set.seed(123)
n = 1e8

df = data.frame(bad=sample(1:3, n, TRUE), worse=rnorm(n))
address(df)
#[1] "0x208f9f00"
colnames(df) <- c("good", "better")
address(df)
#[1] "0x208fa1d8"
rm(df)

dt = data.table(bad=sample(1:3, n, TRUE), worse=rnorm(n))
address(dt)
#[1] "0x535c830"
setnames(dt, c("good", "better"))
address(dt)
#[1] "0x535c830"
rm(dt)

Więc jeśli osiągasz limit pamięci, możesz rozważyć użycie tego.

jangorecki
źródło
3

Może to być pomocne:

rename.columns=function(df,changelist){
  #renames columns of a dataframe
  for(i in 1:length(names(df))){
    if(length(changelist[[names(df)[i]]])>0){
      names(df)[i]= changelist[[names(df)[i]]]
    }
  }
  df
}

# Specify new dataframe
df=rename.columns(df,list(old.column='new.column.name'))
Chris
źródło
1

W przypadku, gdy mamy 2 ramki danych, następujące prace

 DF1<-data.frame('a', 'b')
 DF2<-data.frame('c','d')

Zmieniamy nazwy DF1 w następujący sposób

 colnames(DF1)<- colnames(DF2)
Raghavan vmvs
źródło