Substituição para “renomear” no dplyr

118

Eu gosto da função de renomeação de plyr rename. Recentemente comecei a usar o dplyr e gostaria de saber se existe uma maneira fácil de renomear variáveis ​​usando uma função de dplyr, que seja tão fácil de usar quanto a de plyr rename?

vergilcw
fonte

Respostas:

148

dplyr versão 0.3 adicionou uma nova rename()função que funciona exatamente como plyr::rename().

df <- rename(df, new_name = old_name)
Aaronwolen
fonte
7
Você poderia explicar a sintaxe? Isso é mais importante do que o comando. Estou usando, rename(TheDataFrame,OldVarName=NewVarName)mas entendo Error: Unknown variables: NewVarName.e não entendo o porquê.
s_a
2
@s_a Eu adicionei o esclarecimento. Deve aparecer após revisão.
Ryan
4
Se você tiver problemas, talvez especificar o pacote explicitamente ajude dplyr::rename(iris, petal_length = Petal.Length).
Boern
2
Duas observações rápidas: o comando acima deve ser atribuído ao dataframe para ter efeito iris <- dplyr::rename(iris, petal_length = Petal.Length)e rename () não trata nomes de variáveis ​​com espaços, por exemplo, dplyr::rename(iris, petal_length = "petal length")produz um erro.
Anthony Simon Mielniczuk
2
Você pode usar setNames()se estiver substituindo os nomes das colunas no atacado:df %>% mutate(foo = 1 +2) %>% setNames(c("blah", "blu", "bar"))
crazybilly de
46

A próxima versão do dplyr oferecerá suporte a uma versão aprimorada do select que também incorpora a renomeação:

> 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
fonte
2
Para sua informação changesé exportado (ou deveria ser)
hadley
2
Agradável. A única coisa é que isso significará uma mudança no pensamento por parte do usuário, já que plyra função de renomear de usa "old"="new"enquanto dplyrusa o new=oldque a mantém consistente com o resto das funções dplyr. Pessoalmente, não penso nisso como um problema - você se acostuma com coisas novas rapidamente, especialmente quando isso significa uma aceleração significativa no processamento de dados.
vergilcw
3
Este é o recurso pretendido, daí a escolha do verbo select. Não tenho certeza se temos algo que diz: selecione todas as variáveis ​​e, a propósito, renomeie esta coluna.
Romain François
1
Talvez para evitar confusão, você poderia editar sua postagem de forma que o código refletisse a maneira como selectrealmente se comporta? Eu votaria por uma dplyrmaneira fácil de manter todas as variáveis ​​e apenas renomear uma ou duas. :) Por enquanto, continuarei carregando plyre usando rename.
vergilcw
2
@RomainFrancois @aaronwolen Você pode conseguir o que o OP deseja usando mtcars %>% select(matches(".*"),disp2=disp). Eu adoraria uma solução mais parcimoniosa, mas isso funciona e preserva todas as colunas (embora não sua ordem). dispnão é duplicado.
farnsy
27

Você pode realmente usar plyra renamefunção de como parte de dplyrcadeias. Acho que toda função que a) recebe a data.framecomo primeiro argumento eb) retorna a data.framefunciona para encadeamento. Aqui está um exemplo:

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

ATUALIZAÇÃO: A versão atual do dplyrsuporta renomeação diretamente como parte da selectfunção (veja a postagem de Romain Francois acima). A declaração geral sobre o uso de funções não-dplyr como parte de dplyrchains ainda é válida e renameé um exemplo interessante.

user2503795
fonte
5
É melhor carregar dplyr após plyr neste caso. Dessa forma, as funções dplyr mais rápidas são usadas quando disponíveis e você pode usar mutate em vez de dplyr :: mutate
Vincent
Parece que você está certo sobre poder usar funções não dplyr no encadeamento. mtcars%.% rename (c ("mpg", "cyl"), c ("mympg", "mycyl")) funciona onde renomear é a função definida em minha resposta.
Vincent
Mudei a ordem de carregamento de dplyr e plyr, obrigado.
user2503795 01 de
Esta é uma solução decente, embora traga uma discussão interessante sobre o desempenho em dados maiores, que é uma das principais vantagens do dplyr. Obrigado pela sugestão!
vergilcw
renomeia o trabalho por referência, como setnames do pacote
data.table
9

Não está listado como uma função no dplyr (ainda): http://cran.rstudio.org/web/packages/dplyr/dplyr.pdf

A função abaixo funciona (quase) da mesma forma se você não quiser carregar o plyr e o 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

Editar: O comentário de Romain produz o seguinte (observe que a função de mudanças requer 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
fonte
3
O único problema aqui é que os dados são copiados. Não é grande coisa se for para jogar, ou seja, mtcarsetc ... mas bastante dramático se você lidar com dados substanciais. verificardplyr:::changes(mtcars, dat)
Romain Francois
1
Obrigado pelo comentário Romain. Existe um motivo pelo qual as alterações não são exportadas do dplyr? Parece uma função bastante útil.
Vincent
1
Acho que Hadley o vê principalmente como uma ferramenta de desenvolvimento para nós.
Romain Francois
1
Definitivamente, deve ser exportado. Posso ter esquecido
hadley
2

Embora não seja exatamente renomear, dplyr::select_all()pode ser usado para reformatar os nomes das colunas. Este exemplo substitui espaços e pontos por um sublinhado e converte tudo para minúsculas:

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
fonte
1

Tentei usar dplyr :: rename e recebo um erro:

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

Em vez disso, usei a função R de base, que se revelou bastante simples e eficaz:

names(occ_5d)[1] = "code_5d"
Adams
fonte