Remplacement de «renommer» dans dplyr

118

J'aime la fonction de changement de nom de plyr rename. J'ai récemment commencé à utiliser dplyr et je me demandais s'il existe un moyen simple de renommer des variables en utilisant une fonction de dplyr, qui est aussi facile à utiliser que celle de plyr rename?

vergilcw
la source

Réponses:

148

dplyr version 0.3 a ajouté une nouvelle rename()fonction qui fonctionne exactement comme plyr::rename().

df <- rename(df, new_name = old_name)
Aaronwolen
la source
7
Pouvez-vous expliquer la syntaxe? C'est plus important que la commande. J'utilise rename(TheDataFrame,OldVarName=NewVarName)mais j'obtiens Error: Unknown variables: NewVarName.et je ne comprends pas pourquoi.
s_a
2
@s_a J'ai ajouté la clarification. Il devrait apparaître après examen.
Ryan
4
Si vous rencontrez des problèmes, il est peut-être utile de spécifier explicitement le package dplyr::rename(iris, petal_length = Petal.Length).
Boern
2
Deux observations rapides: la commande ci-dessus doit être affectée au dataframe pour prendre effet iris <- dplyr::rename(iris, petal_length = Petal.Length)et rename () ne gère pas les noms de variables avec des espaces, par exemple, dplyr::rename(iris, petal_length = "petal length")produit une erreur.
Anthony Simon Mielniczuk
2
Vous pouvez utiliser setNames()si vous remplacez les noms de colonnes en gros:df %>% mutate(foo = 1 +2) %>% setNames(c("blah", "blu", "bar"))
crazybilly
46

La prochaine version de dplyr prendra en charge une version améliorée de select qui comprend également le changement de nom:

> 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 François
la source
2
FYI changesest exporté (ou il devrait l'être)
hadley
2
Agréable. La seule chose est que cela signifiera un changement de pensée de la part de l'utilisateur, puisque plyrla fonction de renommage de s utilise "old"="new"alors que les dplyrutilisations la new=oldmaintiennent cohérente avec le reste des fonctions de dplyr. Personnellement, je ne vois pas cela comme un problème - vous vous habituez rapidement à de nouvelles choses surtout quand cela signifie une accélération significative de votre traitement de données.
vergilcw
3
C'est la fonctionnalité recherchée, d'où le choix du verbe select. Pas sûr que nous ayons quelque chose qui dit de sélectionner toutes les variables et d'ailleurs renommer cette colonne.
Romain Francois
1
Peut-être pour éviter toute confusion pourriez-vous modifier votre message afin que le code reflète la façon dont selectse comporte réellement? Je voterais pour un dplyrmoyen facile de conserver toutes les variables et d'en renommer une ou deux. :) Pour l'instant, je vais continuer à charger plyret à utiliser rename.
vergilcw
2
@RomainFrancois @aaronwolen Vous pouvez réaliser ce que l'OP veut en utilisant mtcars %>% select(matches(".*"),disp2=disp). J'adorerais une solution plus parcimonieuse mais cela fonctionne et préserve toutes les colonnes (mais pas leur ordre). dispne se duplique pas.
farnsy
27

Vous pouvez en fait utiliser plyrla renamefonction de dans le cadre de dplyrchaînes. Je pense que chaque fonction que a) prend a data.framecomme premier argument et b) renvoie a data.framefonctionne pour le chaînage. Voici un exemple:

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

MISE À JOUR: La version actuelle de dplyrprend en charge le renommage directement dans le cadre de la selectfonction (voir l'article de Romain François ci-dessus). La déclaration générale sur l'utilisation de fonctions non-dplyr dans le cadre de dplyrchaînes est toujours valable et renameest un exemple intéressant.

user2503795
la source
5
Il est préférable de charger dplyr après plyr dans ce cas. De cette façon, les fonctions plus rapides de dplyr sont utilisées lorsqu'elles sont disponibles et vous pouvez utiliser mutate plutôt que dplyr :: mutate
Vincent
Il semble que vous ayez raison de pouvoir utiliser des fonctions non-dplyr dans le chaînage. mtcars%.% rename (c ("mpg", "cyl"), c ("mympg", "mycyl")) fonctionne où renommer est la fonction définie dans ma réponse.
Vincent
J'ai changé l'ordre de chargement de dplyr et plyr, merci.
user2503795
Il s'agit d'une solution de contournement décente, mais soulève une discussion intéressante sur les performances sur des données plus volumineuses, qui est l'un des principaux avantages de dplyr. Merci pour la suggestion!
vergilcw
le renommage fonctionne par référence comme les noms de jeu du package
data.table
9

Elle n'est pas (encore) répertoriée en tant que fonction dans dplyr: http://cran.rstudio.org/web/packages/dplyr/dplyr.pdf

La fonction ci-dessous fonctionne (presque) la même chose si vous ne voulez pas charger à la fois plyr et 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

Edit: Le commentaire de Romain produit ce qui suit (notez que la fonction de changements nécessite 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
la source
3
Le seul problème ici est que les données sont copiées. Pas grand-chose si c'est pour jouer, c'est-à-dire mtcarsetc ... mais assez dramatique si vous traitez avec des données substantielles. checkdplyr:::changes(mtcars, dat)
Romain Francois
1
Merci pour le commentaire Romain. Y a-t-il une raison pour laquelle les modifications ne sont pas exportées depuis dplyr? Semble une fonction très utile.
Vincent le
1
J'imagine que Hadley le voit principalement comme un outil de développement pour nous.
Romain Francois le
1
Il devrait certainement être exporté. J'ai peut-être juste oublié
hadley
2

Bien qu'il ne soit pas exactement renommé, dplyr::select_all()peut être utilisé pour reformater les noms de colonne. Cet exemple remplace les espaces et les points par un trait de soulignement et convertit tout en minuscules:

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
la source
1

J'ai essayé d'utiliser dplyr :: rename et j'obtiens une erreur:

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

J'ai plutôt utilisé la fonction de base R qui s'avère assez simple et efficace:

names(occ_5d)[1] = "code_5d"
Adams
la source