89 votes

R déplacer une colonne à la dernière en utilisant dplyr

Pour un data.frame avec n J'aimerais pouvoir déplacer une colonne de n'importe laquelle de ces colonnes. 1-(n-1) pour être la nième colonne (c'est-à-dire une colonne qui n'est pas la dernière pour être la dernière colonne). J'aimerais également le faire en utilisant dplyr . Je voudrais le faire sans simplement taper les noms de toutes les colonnes.

Par exemple :

data<-data.frame(a=1:5, b=6:10, c=11:15)

Cela fonctionne, mais ce n'est pas le dplyr manière :

data[,c(colnames(data)[colnames(data)!='b'],'b')]

C'est le dplyr manière de faire la colonne b d'abord :

data%>%select(b, everything())

Mais cela ne fonctionne pas pour faire de la colonne b dernier :

data%>%select(everything(), b)

Cela fonctionne, mais m'oblige à taper toutes les colonnes :

data%>%select(a,c,b)

Existe-t-il un moyen élégant de faire cela avec Dplyr ?

Questions connexes :

137voto

dule arnaux Points 1012

Après quelques bricolages, ce qui suit fonctionne et nécessite très peu de saisie.

data %>% select(-b,b)

MISE À JOUR : dplyr 1.0.0

dplyr 1.0.0 présente le relocate le verbe :

data %>% relocate(b, .after = last_col())

Je préfère encore l'ancienne méthode "hacky".

0 votes

Merci beaucoup pour cette méthode simple et facile. J'apprécie Dule.

1 votes

Dule, vous pourriez changer la réponse acceptée par celle-ci ou celle d'Arthur Yip, car elles sont décidément plus propres et plus "élégantes" que celle d'Arkun (même si elle fonctionne bien).

1 votes

Les autres réponses m'en apprennent plus sur dplyr, mais cette réponse est la plus courte de toutes ! Je la considère donc comme un pile ou face.

77voto

Arthur Yip Points 931

Mise à jour :

dplyr::relocate un nouveau verbe introduit dans dplyr 1.0.0, est maintenant ma solution préférée, car il est explicite sur ce que vous faites, vous pouvez continuer à choisir des variables en utilisant tidyselect et vous pouvez spécifier exactement où placer les colonnes à l'aide de .before ou .after

data %>% relocate(b, .after = last_col()) (identique à la mise à jour de Dule Arnaux)

Réponse originale

data%>%select(-b,everything())

déplacera la variable b à la fin.

Cela est dû au fait qu'une variable négative en première position de select suscite un comportement spécial de select(), qui consiste à insérer toutes les variables. Ensuite, elle supprime b, puis le rajoute avec la partie everything().

Expliqué par Hadley lui-même : https://github.com/tidyverse/dplyr/issues/2838

Consultez également cette autre réponse pour d'autres exemples de déplacement de certaines colonnes vers la fin et d'autres colonnes vers le début : Comment la fonction d'aide de sélection everything() de dplyr diffère-t-elle de la copie ?

3 votes

C'est plus propre que la réponse de dule arnaux si vous déplacez plusieurs colonnes vers l'arrière.

1 votes

Notez que cette réponse ne respecte pas l'ordre des variables, dans le cas où vous passez plusieurs noms, comme par exemple -c(a,b,c) au lieu de seulement -b . Avec cette solution, l'ordre des variables reflétera l'ordre dans lequel elles se trouvaient déjà dans le cadre de données. Ainsi, si l'ordre des colonnes était a, c, b, d, e, f cette réponse renverra d, e, f, a, c, b . La réponse de Dule arnaux reviendra. d, e, f, a, b, c

13voto

akrun Points 148302

Nous pouvons soit utiliser

data %>%
    select(-one_of('b'), one_of('b'))
#  a  c  b
#1 1 11  6
#2 2 12  7
#3 3 13  8
#4 4 14  9
#5 5 15 10

Ou

data %>%
    select(matches("[^b]"), matches("b"))

ou avec le select_

data %>% 
    select_(.dots = c(setdiff(names(.), 'b'), 'b'))
#  a  c  b
#1 1 11  6
#2 2 12  7
#3 3 13  8
#4 4 14  9
#5 5 15 10

1 votes

Excellente réponse toujours, Que fait un_of ? Est-ce qu'il prend réellement le nom entre guillemets, contrairement aux autres options ? Merci

1 votes

@Bankelal Merci. Vous pouvez avoir un vecteur de noms de chaînes dans one_of pour correspondre et le ramasser

2 votes

+1 pour l'utilisation one_of comme protection pour les colonnes manquantes. Combinez avec la réponse d'Arthur Yip pour data %>% select(-one_of('b'), everything()) qui remet la colonne supprimée à la fin avec l'appel everything().

5voto

beginneR Points 7179

Comme il n'y a pas de solution toute faite pour cela dans dplyr, vous pouvez définir votre propre petite fonction qui le fera pour vous :

move_last <- function(DF, last_col) {
    match(c(setdiff(names(DF), last_col), last_col), names(DF))
}

Vous pouvez ensuite l'utiliser facilement dans une select appeler :

mtcars %>% select(move_last(., "mpg")) %>% head()

Vous pouvez également déplacer plusieurs colonnes vers la fin :

mtcars %>% select(move_last(., c("mpg", "cyl"))) %>% head()

Et vous pouvez toujours fournir d'autres arguments pour sélectionner, par exemple pour supprimer une colonne :

mtcars %>% select(move_last(., "mpg"), -carb) %>% head()

1 votes

Pourquoi dites-vous qu'il n'y a pas de solution toute faite dans dplyr ? L'exemple de solution d'Akrun semble en être une.

0 votes

Il est vrai que dplyr le permet, mais Hadley note que déplacer/réorganiser les variables n'est "généralement pas si important, donc vous devrez vous contenter de select() pour le moment". github.com/tidyverse/dplyr/issues/2838

0voto

f2003596 Points 139
df <- df[, c(which(colnames(df) != "YourColumnName"), which(colnames(df) == "YourColumnName"))]

2 votes

Les deux derniers mots de la question sont : utiliser dplyr. Cette réponse n'utilise pas dplyr.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X