Comment modifier cette entrée (avec la séquence: heure, entrée, sortie, fichiers):
Time In Out Files
1 2 3 4
2 3 4 5
À 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 suit df[,c(1,2,3,4)]
. Notez que la première virgule signifie que toutes les lignes sont conservées et que 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 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 une opération de sous-ensemble et de réorganisation de colonne dans une seule commande.
Mise à 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 les suivants ne réorganiseront que certaines colonnes et en rejeteront d’autres:
mtcars %>% select(mpg:disp, hp, wt, gear:qsec, starts_with('carb'))
En savoir plus sur la syntaxe de sélection de 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 aux erreurs, en particulier 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, sans vous soucier des autres colonnes.
##arrange df vars by position
##'vars' must be a named vector, e.g. 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 demande 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 échanger en plus les colonnes Time
et Files
, procédez comme suit:
arrange.vars(table, c("Out"=2, "Files"=1, "Time"=4))
## Files Out In Time
##1 4 3 2 1
##2 5 4 3 2
C’est peut-être une coïncidence si l’ordre des colonnes que vous souhaitez avoir a des noms de colonnes en ordre alphabétique décroissant. Puisque 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.
Une solution tidyverse
consiste à utiliser select
:
select(table, "Time", "Out", "In", "Files")
# or
select(table, Time, Out, In, Files)
Si vous pouvez utiliser le package data.table, cela constitue un moyen simple et efficace
Comment réorganiser les colonnes de data.table (sans les copier)
setcolorder(DT,myOrder)
Les troismieux notésréponses ont une faiblesse.
Si votre image de données 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)]
Cela fait le travail, mais vous venez d'introduire une dépendance sur l'ordre des colonnes dans votre entrée.
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 assez agréable car il isole complètement les littéraux. En revanche, si vous utilisez select
de dplyr
data <- data %>% select(Time, out, In, Files)
ensuite, vous configurerez ceux qui liront votre code plus tard, vous-même inclus, pour vous tromper un peu. Les noms de colonne sont utilisés comme des littéraux sans apparaître dans le code en tant que tels.
data.table::setcolorder(table, c("Out", "in", "files"))
Le seul que j'ai vu bien travailler est de 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.