web-dev-qa-db-fra.com

Comment renommer des colonnes sélectionnées en utilisant dplyr avec de nouveaux noms de colonnes sous forme de chaînes

J'ai le tibble suivant:

library(tidyverse)
df <- structure(list(Sepal.Length = c(5.1, 4.9, 4.7, 4.6, 5), Sepal.Width = c(3.5, 
3, 3.2, 3.1, 3.6), Petal.Length = c(1.4, 1.4, 1.3, 1.5, 1.4)), .Names = c("Sepal.Length", 
"Sepal.Width", "Petal.Length"), row.names = c(NA, 5L), class = c("tbl_df", 
"tbl", "data.frame"))

Cela ressemble à ceci:

> df
# A tibble: 5 × 3
  Sepal.Length Sepal.Width Petal.Length
*        <dbl>       <dbl>        <dbl>
1          5.1         3.5          1.4
2          4.9         3.0          1.4
3          4.7         3.2          1.3
4          4.6         3.1          1.5
5          5.0         3.6          1.4

Ce que je veux faire est de remplacer Sepal.Length et Petal.Length par la chaîne ajoutée to_app <- ".xxx", ce qui entraîne:

  Sepal.Length.xxx Sepal.Width Petal.Length.xxx
          5.1         3.5          1.4
          4.9         3.0          1.4
          4.7         3.2          1.3
          4.6         3.1          1.5
          5.0         3.6          1.4

J'ai essayé ceci avec erreur:

>df %>% rename(paste(Sepal.Length,to_app,sep="") = Petal.Length,paste(Sepal.Width,to_app,sep="") = Petal.Length)
Error: unexpected '=' in "df %>% rename(paste(Sepal.Length,to_app,sep="") ="
6
neversaint

Si vous souhaitez utiliser la fonction rename de dplyr, il est préférable de créer un vecteur/une liste nommée et de l'appeler à l'aide de l'argument .dots dans la version d'évaluation standard:

cols <- c("Sepal.Length", "Petal.Length")
to_app <- ".xxx"
cols <- setNames(cols, paste0(cols, to_app))

df %>% rename_(.dots = cols)

## A tibble: 5 × 3
#  Sepal.Length.xxx Sepal.Width Petal.Length.xxx
#*            <dbl>       <dbl>            <dbl>
#1              5.1         3.5              1.4
#2              4.9         3.0              1.4
#3              4.7         3.2              1.3
#4              4.6         3.1              1.5
#5              5.0         3.6              1.4

Notez toutefois que cette approche est susceptible de changer avec la prochaine version 0.6.0 de dplyr (voir par exemple http://blog.rstudio.org/2017/04/13/dplyr-0-6-0-coming- bientôt/ et http://dplyr.tidyverse.org/articles/programming.html ).

9
docendo discimus

Vous pouvez utiliser la fonction rename_at pour cela (à partir de dplyr_0.7.0 ).

Par exemple, vous pouvez transmettre les variables que vous souhaitez renommer sous forme de chaînes. Dans votre exemple, la fonction paste0 peut être utilisée pour ajouter le suffixe approprié à chaque colonne.

cols = c("Sepal.Length", "Petal.Length")
to_app = ".xxx"

rename_at(df, cols, funs( paste0(., to_app) ) )

# A tibble: 5 x 3
  Sepal.Length.xxx Sepal.Width Petal.Length.xxx
*            <dbl>       <dbl>            <dbl>
1              5.1         3.5              1.4
2              4.9         3.0              1.4
3              4.7         3.2              1.3
4              4.6         3.1              1.5
5              5.0         3.6              1.4

Vous pouvez également utiliser les fonctions auxiliaires de sélection pour choisir des variables à renommer, telles que contains.

rename_at(df, vars( contains("Length") ), funs( paste0(., ".xxx") ) )

# A tibble: 5 x 3
  Sepal.Length.xxx Sepal.Width Petal.Length.xxx
*            <dbl>       <dbl>            <dbl>
1              5.1         3.5              1.4
2              4.9         3.0              1.4
3              4.7         3.2              1.3
4              4.6         3.1              1.5
5              5.0         3.6              1.4
8
aosmith

Je suis un peu en retard pour la fête à ce sujet, mais après avoir longtemps regardé la vignette programming , j’ai trouvé l’exemple pertinent dans la variable Différentes entrées et sorties .

Dans mon cas d'utilisation plus simple, je devais simplement renommer une colonne avec la valeur d'une chaîne:

> df1 = data_frame(index = 1:5, value = c(10, 20, 30, 40, 50))
> df1
# A tibble: 5 x 2
  index value
  <int> <dbl>
1     1    10
2     2    20
3     3    30
4     4    40
5     5    50

> newname = 'blau'
> newname2 = 'wheee'

> df1 %>% rename(!!newname := value, !!newname2 := index)
# A tibble: 5 x 2
  wheee  blau
  <int> <dbl>
1     1    10
2     2    20
3     3    30
4     4    40
5     5    50

Donc, si vous êtes heureux de le faire manuellement, vous pouvez simplement:

df %>%
  rename(!!paste("Sepal.Length", "xxx", sep = ".") := Sepal.Length)

Si, toutefois, vous avez besoin de quelque chose qui ajoute automatiquement ".xxx" à quel que soit le nom de colonne qui lui est fourni, je vous recommande de regarder de plus près cette section. C'est encore un peu au dessus de ma tête, malheureusement, mais je peux voir que c'est faisable> _>

7
rensa
df %>% setNames(paste0(names(.), to.app))

# A tibble: 5 × 3
  Sepal.Length.xxx Sepal.Width.xxx Petal.Length.xxx
*            <dbl>           <dbl>            <dbl>
1              5.1             3.5              1.4
2              4.9             3.0              1.4
3              4.7             3.2              1.3
4              4.6             3.1              1.5
5              5.0             3.6              1.4

MODIFIER:

Toutes mes excuses pour ne pas lire correctement. Voici une solution avec le package data.table.

var <- names(df)[c(1,3)]
df %>% setnames(., var, paste0(var, to.app))
df

# A tibble: 5 × 3
  Sepal.Length.xxx Sepal.Width Petal.Length.xxx
*            <dbl>       <dbl>            <dbl>
1              5.1         3.5              1.4
2              4.9         3.0              1.4
3              4.7         3.2              1.3
4              4.6         3.1              1.5
5              5.0         3.6              1.4
3
Adam Quek

En supposant que le but est de renommer toutes les colonnes contenant "Length":

colnames(df) <- ifelse(grepl("Length", colnames(df)), 
                       paste0(colnames(df), to_app), 
                       colnames(df))
2
neilfws

Le mieux que je puisse faire dans la version de développement de dplyr (à paraître le 11 mai):

cols <- c("Sepal.Length", "Petal.Length")
to_app <- ".xxx"
ns <- paste0(cols, to_app)

rename(df, 
       !!ns[1] := !!as.name(cols[1]), 
       !!ns[2] := !!as.name(cols[2]))

Pour le faire entièrement par programmation, il faut plutôt utiliser quos:

xx <- do.call(quos, setNames(map(cols, as.name), ns))
rename(df, !!!xx)

Les deux donnent:

# A tibble: 5 × 3
  Sepal.Length.xxx Sepal.Width Petal.Length.xxx
*            <dbl>       <dbl>            <dbl>
1              5.1         3.5              1.4
2              4.9         3.0              1.4
3              4.7         3.2              1.3
4              4.6         3.1              1.5
5              5.0         3.6              1.4

Bon mot:

rename(df, !!!do.call(quos, setNames(map(cols, as.name), paste0(cols, to_app))))
1
Axeman