Zamiennik dla „rename” w dplyr

118

Podoba mi się funkcja zmiany nazwy Plyra rename. Niedawno zacząłem używać dplyr i zastanawiałem się, czy istnieje łatwy sposób zmiany nazw zmiennych za pomocą funkcji z dplyr, która jest tak łatwa w użyciu, jak w przypadku Plyr rename?

vergilcw
źródło

Odpowiedzi:

148

dplyr w wersji 0.3 dodał nową rename()funkcję, która działa tak samo plyr::rename().

df <- rename(df, new_name = old_name)
aaronwolen
źródło
7
Czy mógłbyś wyjaśnić składnię? To ważniejsze niż polecenie. Używam, rename(TheDataFrame,OldVarName=NewVarName)ale dostaję Error: Unknown variables: NewVarName.i nie rozumiem dlaczego.
s_a,
2
@s_a Dodałem wyjaśnienie. Powinien pojawić się po sprawdzeniu.
Ryan,
4
Jeśli masz problemy, być może określenie pakietu wyraźnie pomoże dplyr::rename(iris, petal_length = Petal.Length).
Boern
2
Dwie krótkie spostrzeżenia: powyższe polecenie musi zostać przypisane do ramki danych, aby zadziałało, a funkcja iris <- dplyr::rename(iris, petal_length = Petal.Length)rename () nie obsługuje nazw zmiennych ze spacjami, na przykład dplyr::rename(iris, petal_length = "petal length")powoduje błąd.
Anthony Simon Mielniczuk
2
Możesz użyć, setNames()jeśli zastępujesz hurtowo nazwy kolumn:df %>% mutate(foo = 1 +2) %>% setNames(c("blah", "blu", "bar"))
crazybilly
46

Następna wersja dplyr będzie obsługiwać ulepszoną wersję select, która obejmuje również zmianę nazwy:

> mtcars2 <- select( mtcars, disp2 = disp )
> head( mtcars2 )
                  disp2
Mazda RX4         160
Mazda RX4 Wag     160
Datsun 710        108
Hornet 4 Drive    258
Hornet Sportabout 360
Valiant           225
> changes( mtcars, mtcars2 )
Changed variables:
      old         new
disp  0x105500400
disp2             0x105500400

Changed attributes:
      old         new
names 0x106d2cf50 0x106d28a98
Romain Francois
źródło
2
FYI changesjest eksportowane (lub powinno być)
Hadley
2
Miły. Jedyną rzeczą jest to, że będzie to oznaczać zmianę myślenia po stronie użytkownika, ponieważ plyrfunkcja zmiany nazwy używa, "old"="new"podczas gdy dplyrużywa, new=oldktóra zachowuje spójność z resztą funkcji dplyr. Osobiście nie uważam tego za problem - szybko przyzwyczajasz się do nowych rzeczy, zwłaszcza gdy oznacza to znaczne przyspieszenie przetwarzania danych.
vergilcw
3
To jest zamierzona funkcja, stąd wybór czasownika select. Nie jestem pewien, czy mamy coś, co mówi, wybierz wszystkie zmienne i przy okazji zmień nazwę tej kolumny.
Romain Francois
1
Być może, aby uniknąć nieporozumień, mógłbyś zmodyfikować swój post tak, aby kod odzwierciedlał sposób, w jaki selectfaktycznie się zachowuje? Głosowałbym za prostym dplyrsposobem na zachowanie wszystkich zmiennych i po prostu zmianę nazwy jednej lub dwóch. :) Na razie będę ładować plyri używać rename.
vergilcw
2
@RomainFrancois @aaronwolen Możesz osiągnąć to, czego chce PO mtcars %>% select(matches(".*"),disp2=disp). Chciałbym mieć bardziej oszczędne rozwiązanie, ale to działa i zachowuje wszystkie kolumny (choć nie ich kolejność). dispnie jest duplikowany.
farnsy
27

Rzeczywiście można użyć plyr„s renamefunkcję jako część dplyrłańcuchów. Myślę, że każda funkcja, która a) przyjmuje a data.framejako pierwszy argument i b) zwraca data.frameprace do łączenia w łańcuch. Oto przykład:

library('plyr')
library('dplyr')

DF = data.frame(var=1:5)

DF %>%
    # `rename` from `plyr`
    rename(c('var'='x')) %>%
    # `mutate` from `dplyr` (note order in which libraries are loaded)
    mutate(x.sq=x^2)

#   x x.sq
# 1 1    1
# 2 2    4
# 3 3    9
# 4 4   16
# 5 5   25

AKTUALIZACJA: Obecna wersja dplyrobsługuje zmianę nazwy bezpośrednio jako część selectfunkcji (patrz post Romain Francois powyżej). Ogólne stwierdzenie dotyczące używania funkcji innych niż dplyr jako części dplyrłańcuchów jest jednak nadal aktualne i renamejest interesującym przykładem.

user2503795
źródło
5
W takim przypadku najlepiej jest ładować dplyr po plyr. W ten sposób szybsze funkcje dplyr są używane, gdy są dostępne, i możesz użyć mutate zamiast dplyr :: mutate
Vincent
Wygląda na to, że masz rację co do możliwości używania funkcji innych niż dplyr w tworzeniu łańcuchów. mtcars%.% rename (c ("mpg", "cyl"), c ("mympg", "mycyl")) działa, gdzie rename jest funkcją zdefiniowaną w mojej odpowiedzi.
Vincent
Zmieniłem kolejność ładowania dplyr i plyr, dzięki.
user2503795
To przyzwoite obejście, choć wywołuje interesującą dyskusję na temat wydajności na większych danych, która jest jedną z głównych zalet dplyr. Dzieki za sugestie!
vergilcw
czy zmiana nazwy działa przez odniesienie, jak setnames z pakietu
data.table
9

Nie jest wymieniony jako funkcja w dplyr (jeszcze): http://cran.rstudio.org/web/packages/dplyr/dplyr.pdf

Poniższa funkcja działa (prawie) tak samo, jeśli nie chcesz ładować zarówno plyr, jak i dplyr

rename <- function(dat, oldnames, newnames) {
  datnames <- colnames(dat)
  datnames[which(datnames %in% oldnames)] <- newnames
  colnames(dat) <- datnames
  dat
}

dat <- rename(mtcars,c("mpg","cyl"), c("mympg","mycyl"))
head(dat)

                  mympg mycyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4          21.0     6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag      21.0     6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710         22.8     4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive     21.4     6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout  18.7     8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant            18.1     6  225 105 2.76 3.460 20.22  1  0    3    1

Edycja: komentarz Romaina daje następujące wyniki (zauważ, że funkcja zmiany wymaga dplyr .1.1)

> dplyr:::changes(mtcars, dat)
Changed variables:
          old         new        
disp      0x108b4b0e0 0x108b4e370
hp        0x108b4b210 0x108b4e4a0
drat      0x108b4b340 0x108b4e5d0
wt        0x108b4b470 0x108b4e700
qsec      0x108b4b5a0 0x108b4e830
vs        0x108b4b6d0 0x108b4e960
am        0x108b4b800 0x108b4ea90
gear      0x108b4b930 0x108b4ebc0
carb      0x108b4ba60 0x108b4ecf0
mpg       0x1033ee7c0            
cyl       0x10331d3d0            
mympg                 0x108b4e110
mycyl                 0x108b4e240

Changed attributes:
          old         new        
names     0x10c100558 0x10c2ea3f0
row.names 0x108b4bb90 0x108b4ee20
class     0x103bd8988 0x103bd8f58
Vincent
źródło
3
Jedynym problemem jest to, że dane są kopiowane. Nic wielkiego, jeśli chodzi o grę, np. mtcarsItp., Ale dość dramatyczne, jeśli masz do czynienia z istotnymi danymi. czekdplyr:::changes(mtcars, dat)
Romain Francois
1
Dzięki za komentarz Romain. Czy istnieje powód, dla którego zmiany nie są eksportowane z dplyr? Wydaje się całkiem przydatna funkcja.
Vincent
1
Wydaje mi się, że Hadley postrzega to głównie jako narzędzie programistyczne dla nas.
Romain Francois
1
Zdecydowanie powinien zostać wyeksportowany. Mogłem po prostu zapomnieć
hadley
2

Chociaż dplyr::select_all()nazwa nie jest dokładnie zmieniana, może służyć do ponownego formatowania nazw kolumn. Ten przykład zastępuje spacje i kropki podkreśleniem i konwertuje wszystko na małe litery:

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
1

Próbowałem użyć dplyr :: rename i otrzymuję błąd:

occ_5d <- dplyr::rename(occ_5d, rowname='code_5d')
Error: Unknown column `code_5d` 
Call `rlang::last_error()` to see a backtrace

Zamiast tego użyłem podstawowej funkcji R, która okazała się dość prosta i skuteczna:

names(occ_5d)[1] = "code_5d"
Adams
źródło