Thay thế cho "đổi tên" trong dplyr


118

Tôi thích chức năng đổi tên của plyr rename. Gần đây tôi đã bắt đầu sử dụng dplyr và tự hỏi liệu có cách nào dễ dàng để đổi tên các biến bằng cách sử dụng một hàm từ dplyr, điều đó có dễ sử dụng như plyr renamekhông?

Câu trả lời:


148

dplyr phiên bản 0.3 đã thêm một rename()chức năng mới hoạt động giống như plyr::rename().

df <- rename(df, new_name = old_name)

7
Bạn có thể giải thích cú pháp? Điều đó quan trọng hơn lệnh. Tôi đang sử dụng rename(TheDataFrame,OldVarName=NewVarName)nhưng tôi nhận được Error: Unknown variables: NewVarName.và tôi không hiểu tại sao.
s_a

2
@s_a Tôi đã thêm phần làm rõ. Nó sẽ hiển thị sau khi xem xét.
Ryan

4
Nếu bạn gặp sự cố, có thể chỉ định gói một cách rõ ràng sẽ hữu ích dplyr::rename(iris, petal_length = Petal.Length).
Boern

2
Hai quan sát nhanh: lệnh trên phải được gán cho khung dữ liệu để có hiệu lực iris <- dplyr::rename(iris, petal_length = Petal.Length)và rename () không xử lý các tên biến có dấu cách, chẳng hạn, dplyr::rename(iris, petal_length = "petal length")tạo ra lỗi.
Anthony Simon Mielniczuk

2
Bạn có thể sử dụng setNames()nếu bạn đang thay thế các tên cột bán buôn:df %>% mutate(foo = 1 +2) %>% setNames(c("blah", "blu", "bar"))
crazybilly

46

Phiên bản tiếp theo của dplyr sẽ hỗ trợ một phiên bản chọn cải tiến cũng bao gồm đổi tên:

> 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

2
FYI changesđược xuất (hoặc nó nên được xuất)
hadley

2
Đẹp. Chỉ có điều là điều này sẽ có nghĩa là một sự thay đổi trong suy nghĩ từ phía người dùng, vì plyrhàm đổi tên của sử dụng "old"="new"trong khi cách dplyrsử dụng new=oldgiữ cho nó nhất quán với phần còn lại của các hàm dplyr. Cá nhân tôi không nghĩ đó là một vấn đề - bạn sẽ nhanh chóng làm quen với những thứ mới, đặc biệt khi nó có nghĩa là tốc độ xử lý dữ liệu của bạn tăng lên đáng kể.
vergilcw

3
Đây là đặc điểm dự định, do đó là sự lựa chọn của động từ select. Không chắc chúng ta có một cái gì đó nói rằng hãy chọn tất cả các biến và nhân tiện đổi tên cột này.
Romain Francois

1
Có lẽ để tránh nhầm lẫn, bạn có thể chỉnh sửa bài đăng của mình để mã phản ánh cách selectthực sự hoạt động không? Tôi sẽ bỏ phiếu cho một dplyrcách dễ dàng để giữ tất cả các biến và chỉ cần đổi tên một hoặc hai. :) Còn bây giờ tôi sẽ tiếp tục tải plyrvà sử dụng rename.
vergilcw

2
@RomainFrancois @aaronwolen Bạn có thể đạt được những gì OP muốn bằng cách sử dụng mtcars %>% select(matches(".*"),disp2=disp). Tôi rất thích một giải pháp phân tích cú pháp hơn nhưng điều này hoạt động và bảo toàn tất cả các cột (mặc dù không phải thứ tự của chúng). dispkhông bị trùng lặp.
farnsy

27

Bạn thực sự có thể sử dụng plyr's renamechức năng như một phần của dplyrchuỗi. Tôi nghĩ rằng mọi hàm mà a) lấy a data.framelàm đối số đầu tiên và b) trả về một data.framehoạt động cho chuỗi. Đây là một ví dụ:

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

CẬP NHẬT: Phiên bản hiện tại của dplyrhỗ trợ đổi tên trực tiếp như một phần của selecthàm (xem bài đăng của Romain Francois ở trên). Tuyên bố chung về việc sử dụng các hàm không phải dplyr như một phần của dplyrchuỗi vẫn có giá trị và renamelà một ví dụ thú vị.


5
Tốt nhất là tải dplyr sau plyr trong trường hợp này. Bằng cách đó, các hàm dplyr nhanh hơn được sử dụng khi có sẵn và bạn có thể sử dụng mutate thay vì dplyr :: mutate
Vincent

Có vẻ như bạn đã đúng khi có thể sử dụng các hàm không phải dplyr trong chuỗi. mtcars%.% rename (c ("mpg", "cyl"), c ("mympg", "mycyl")) hoạt động trong đó rename là hàm được xác định trong câu trả lời của tôi.
Vincent

Tôi đã thay đổi thứ tự tải của dplyr và plyr, cảm ơn.
user2503795

Đây là một giải pháp tốt, mặc dù mang đến một cuộc thảo luận thú vị về hiệu suất trên dữ liệu lớn hơn, đây là một trong những lợi thế chính của dplyr. Cám ơn vì sự gợi ý!
vergilcw

Đổi tên có hoạt động bằng cách tham chiếu như tên đặt từ gói
data.table không

9

Nó không được liệt kê là một hàm trong dplyr (chưa): http://cran.rstudio.org/web/packages/dplyr/dplyr.pdf

Hàm bên dưới hoạt động (gần như) giống nhau nếu bạn không muốn tải cả plyr và 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

Chỉnh sửa: Nhận xét của Romain tạo ra như sau (lưu ý rằng chức năng thay đổi yêu cầu 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

3
Vấn đề duy nhất ở đây là dữ liệu được sao chép. Không có vấn đề gì lớn nếu đây là để chơi, tức là mtcarsvv ... nhưng khá kịch tính nếu bạn xử lý dữ liệu quan trọng. kiểm tradplyr:::changes(mtcars, dat)
Romain Francois

1
Cảm ơn vì bình luận của Romain. Có lý do gì khiến các thay đổi không được xuất từ ​​dplyr? Có vẻ như một chức năng khá hữu ích.
Vincent

1
Tôi đoán hadley chủ yếu coi nó như một công cụ phát triển cho chúng tôi.
Romain Francois

1
Nó chắc chắn nên được xuất khẩu. Tôi có thể vừa quên
hadley

2

Mặc dù không đổi tên chính xác, nhưng dplyr::select_all()có thể được sử dụng để định dạng lại tên cột. Ví dụ này thay thế dấu cách và dấu chấm bằng dấu gạch dưới và chuyển đổi mọi thứ thành chữ thường:

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

1

Tôi đã cố gắng sử dụng dplyr :: rename và tôi gặp lỗi:

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

Thay vào đó, tôi đã sử dụng hàm R cơ sở hóa ra khá đơn giản và hiệu quả:

names(occ_5d)[1] = "code_5d"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.