Comment réorganiser les colonnes dans un bloc de données?

Comment changerait-on cette entrée (avec la séquence: time, in, out, files):

Time In Out Files 1 2 3 4 2 3 4 5 

A cette sortie (avec la séquence: time, out, in, files)?

 Time Out In Files 1 3 2 4 2 4 3 5 

Voici les données factices R:

 table <- data.frame(Time=c(1,2), In=c(2,3), Out=c(3,4), Files=c(4,5)) table ## Time In Out Files ##1 1 2 3 4 ##2 2 3 4 5 

Votre dataframe a quatre colonnes comme si df[,c(1,2,3,4)] . Notez que la première virgule signifie conserver toutes les lignes et que le 1,2,3,4 fait référence aux colonnes.

Pour changer l’ordre comme dans la question ci-dessus, faites df2[,c(1,3,2,4)]

Si vous voulez sortir ce fichier en tant que fichier csv, faites write.csv(df2, file="somedf.csv")

 # reorder by column name data <- data[c("A", "B", "C")] #reorder by column index data <- data[c(1,3,2)] 

Vous pouvez également utiliser la fonction de sous-ensemble:

 data <- subset(data, select=c(3,2,1)) 

Vous devriez mieux utiliser l'opérateur [] comme dans les autres réponses, mais il peut être utile de savoir que vous pouvez effectuer un sous-ensemble et une opération de réordonnancement de colonne en une seule commande.

Mettre à jour:

Vous pouvez également utiliser la fonction select du package dplyr:

 data = data %>% select(Time, out, In, Files) 

Je ne suis pas sûr de l'efficacité, mais grâce à la syntaxe de dplyr, cette solution devrait être plus flexible, surtout si vous avez beaucoup de colonnes. Par exemple, les éléments suivants réorganiseront les colonnes du jeu de données mtcars dans l'ordre inverse:

 mtcars %>% select(carb:mpg) 

Et ce qui suit ne réordonnera que certaines colonnes et en supprimera d'autres:

 mtcars %>% select(mpg:disp, hp, wt, gear:qsec, starts_with('carb')) 

En savoir plus sur la syntaxe choisie par dplyr .

Comme mentionné dans ce commentaire , les suggestions standard pour réorganiser les colonnes dans un data.frame sont généralement lourdes et sujettes à des erreurs, surtout si vous avez beaucoup de colonnes.

Cette fonction permet de réorganiser les colonnes par position: spécifiez un nom de variable et la position souhaitée, et ne vous préoccupez pas des autres colonnes.

 ##arrange df vars by position ##'vars' must be a named vector, eg c("var.name"=1) arrange.vars <- function(data, vars){ ##stop if not a data.frame (but should work for matrices as well) stopifnot(is.data.frame(data)) ##sort out inputs data.nms <- names(data) var.nr <- length(data.nms) var.nms <- names(vars) var.pos <- vars ##sanity checks stopifnot( !any(duplicated(var.nms)), !any(duplicated(var.pos)) ) stopifnot( is.character(var.nms), is.numeric(var.pos) ) stopifnot( all(var.nms %in% data.nms) ) stopifnot( all(var.pos > 0), all(var.pos <= var.nr) ) ##prepare output out.vec <- character(var.nr) out.vec[var.pos] <- var.nms out.vec[-var.pos] <- data.nms[ !(data.nms %in% var.nms) ] stopifnot( length(out.vec)==var.nr ) ##re-arrange vars by position data <- data[ , out.vec] return(data) } 

Maintenant, la requête de l'OP devient aussi simple que cela:

 table <- data.frame(Time=c(1,2), In=c(2,3), Out=c(3,4), Files=c(4,5)) table ## Time In Out Files ##1 1 2 3 4 ##2 2 3 4 5 arrange.vars(table, c("Out"=2)) ## Time Out In Files ##1 1 3 2 4 ##2 2 4 3 5 

Pour permuter en plus les colonnes Time et Files vous pouvez le faire:

 arrange.vars(table, c("Out"=2, "Files"=1, "Time"=4)) ## Files Out In Time ##1 4 3 2 1 ##2 5 4 3 2 

Peut-être est-ce une coïncidence que l’ordre des colonnes que vous voulez arrive à avoir des noms de colonnes dans l’ordre alphabétique décroissant. Comme c’est le cas, vous pouvez simplement faire:

 df<-df[,order(colnames(df),decreasing=TRUE)] 

C'est ce que j'utilise quand j'ai de gros fichiers avec beaucoup de colonnes.

Si vous pouvez utiliser le package data.table, cela fournit un moyen compact et efficace

Comment réorganiser les colonnes data.table (sans copier)

 setcolorder(DT,myOrder) 

Une solution tidyverse consiste à utiliser select comme dans:

 select(table, "Time", "Out", "In", "Files") 

Les trois réponses les mieux notées présentent une faiblesse.

Si votre dataframe ressemble à ceci

 df <- data.frame(Time=c(1,2), In=c(2,3), Out=c(3,4), Files=c(4,5)) > df Time In Out Files 1 1 2 3 4 2 2 3 4 5 

alors c’est une mauvaise solution à utiliser

 > df2[,c(1,3,2,4)] 

Il fait le travail, mais vous venez d’introduire une dépendance à l’ordre des colonnes dans votre saisie.

Ce style de programmation fragile doit être évité.

La dénomination explicite des colonnes est une meilleure solution

 data[,c("Time", "Out", "In", "Files")] 

De plus, si vous avez l’intention de réutiliser votre code dans un contexte plus général, vous pouvez simplement

 out.column.name <- "Out" in.column.name <- "In" data[,c("Time", out.column.name, in.column.name, "Files")] 

ce qui est également très bien car il isole complètement les littéraux. En revanche, si vous utilisez la select de dplyr

 data <- data %>% select(Time, out, In, Files) 

alors vous établiriez ceux qui liront votre code plus tard, y compris vous-même, pour un peu de déception. Les noms de colonne sont utilisés comme littéraux sans apparaître dans le code en tant que tel.

Le seul que j’ai vu bien travailler est d’ ici .

  shuffle_columns <- function (invec, movecommand) { movecommand <- lapply(strsplit(strsplit(movecommand, ";")[[1]], ",|\\s+"), function(x) x[x != ""]) movelist <- lapply(movecommand, function(x) { Where <- x[which(x %in% c("before", "after", "first", "last")):length(x)] ToMove <- setdiff(x, Where) list(ToMove, Where) }) myVec <- invec for (i in seq_along(movelist)) { temp <- setdiff(myVec, movelist[[i]][[1]]) A <- movelist[[i]][[2]][1] if (A %in% c("before", "after")) { ba <- movelist[[i]][[2]][2] if (A == "before") { after <- match(ba, temp) - 1 } else if (A == "after") { after <- match(ba, temp) } } else if (A == "first") { after <- 0 } else if (A == "last") { after <- length(myVec) } myVec <- append(temp, values = movelist[[i]][[1]], after = after) } myVec } 

Utilisez comme ceci:

 new_df <- iris[shuffle_columns(names(iris), "Sepal.Width before Sepal.Length")] 

Fonctionne comme un charme.