Wie reorganisiert man Spalten in einem Datenrahmen?

Wie würde man diese Eingabe ändern (mit der Sequenz: time, in, out, files):

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

Zu dieser Ausgabe (mit der Sequenz: time, out, in, files)?

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

Hier sind die Dummy-R-Daten:

 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 

Solutions Collecting From Web of "Wie reorganisiert man Spalten in einem Datenrahmen?"

Ihr Datenrahmen hat vier Spalten wie df[,c(1,2,3,4)] . Beachten Sie, dass das erste Komma bedeutet, dass alle Zeilen beibehalten werden, und dass 1,2,3,4 sich auf die Spalten bezieht.

Um die Reihenfolge wie in der obigen Frage zu df2[,c(1,3,2,4)] tun df2[,c(1,3,2,4)]

Wenn Sie diese Datei als csv write.csv(df2, file="somedf.csv") Sie 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)] 

Sie können auch die Teilmengenfunktion verwenden:

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

Sie sollten besser den Operator [] wie in den anderen Antworten verwenden, aber es kann nützlich sein zu wissen, dass Sie eine Teilmengen- und eine Spaltenneuordnung in einem einzigen Befehl durchführen können.

Aktualisieren:

Sie können auch die Auswahlfunktion aus dem dplyr-Paket verwenden:

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

Ich bin mir nicht sicher über die Effizienz, aber dank der Syntax von dplyr sollte diese Lösung flexibler sein, besonders wenn Sie viele Spalten haben. Im folgenden Beispiel werden die Spalten des mtcars-Datasets in der umgekehrten Reihenfolge neu angeordnet:

 mtcars %>% select(carb:mpg) 

Und im Folgenden werden nur einige Spalten neu angeordnet und andere verworfen:

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

Lesen Sie mehr über die Auswahlsyntax von dplyr .

Wie in diesem Kommentar erwähnt , sind die Standardvorschläge zum data.frame Spalten in einem data.frame im Allgemeinen umständlich und errorsanfällig, insbesondere wenn Sie viele Spalten haben.

Mit dieser function können Sie Spalten nach Position neu anordnen: Geben Sie einen Variablennamen und die gewünschte Position an, und kümmern Sie sich nicht um die anderen Spalten.

 ##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) } 

Jetzt wird die Anfrage des OP so einfach:

 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 

Um die Spalten Time und Files zusätzlich zu vertauschen, können Sie Folgendes tun:

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

Vielleicht ist es Zufall, dass die Spaltenreihenfolge alphabetisch sortiert ist. Da das der Fall ist, könntest du einfach tun:

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

Das verwende ich, wenn ich große Dateien mit vielen Spalten habe.

Wenn Sie das Paket data.table verwenden können, bietet dies eine gute und kompakte Möglichkeit

So ordnen Sie data.table-Spalten neu an (ohne zu kopieren)

 setcolorder(DT,myOrder) 

Eine tidyverse Lösung ist die select wie in:

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

Die drei besten Antworten haben eine Schwäche.

Wenn Ihr Datenrahmen so aussieht

 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 

dann ist es eine schlechte Lösung zu verwenden

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

Es macht den Job, aber Sie haben gerade eine Abhängigkeit von der Reihenfolge der Spalten in Ihrer Eingabe eingeführt.

Diese Art der spröden Programmierung ist zu vermeiden.

Die explizite Benennung der Spalten ist eine bessere Lösung

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

Wenn Sie Ihren Code in einer allgemeineren Umgebung wiederverwenden möchten, können Sie dies einfach tun

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

Das ist auch ziemlich nett, weil es Literale vollständig isoliert. Im Gegensatz dazu, wenn Sie dplyr's select

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

dann würden Sie diejenigen einstellen, die später Ihren Code lesen werden, einschließlich Sie selbst, für ein bisschen Täuschung. Die Spaltennamen werden als Literale verwendet, ohne dass sie im Code erscheinen.

Der einzige, den ich gesehen habe, ist gut von hier .

  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 } 

Verwenden Sie so:

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

Klappt wunderbar.