Cum ar schimba acest lucru de intrare (cu secvența: timp de, în, afară, fișiere):
Time In Out Files
1 2 3 4
2 3 4 5
La această ieșire (cu secvența: timp, afară, înăuntru, fișiere)?
Time Out In Files
1 3 2 4
2 4 3 5
Aici's manechinul R date de:
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
Ta dataframe are patru coloane ca asa df[,c(1,2,3,4)]
.
Notă prima virgulă înseamnă a păstra toate rândurile, și 1,2,3,4 se referă la coloane.
Pentru a schimba ordinea în întrebarea de mai sus fac df2[,c(1,3,2,4)]`
Dacă doriți să ieșire acest fișier csv, nu scrie.csv(df2, file="somedf.csv")
Puteți folosi, de asemenea, subset funcția:
data <- subset(data, select=c(3,2,1))
Ar trebui să utilizați [] operatorul ca și în alte răspunsuri, dar ar putea fi util să știi că poți să faci un subset și o coloană reordona funcționarea într-o singură comandă.
Update:
Puteți folosi, de asemenea, selectați funcția de dplyr pachet:
data = data %>% select(Time, out, In, Files)
Eu nu sunt sigur despre eficiența, dar, datorită dplyr's sintaxa această soluție ar trebui să fie mai flexibile, în special dacă aveți o mulțime de coloane. De exemplu, următorul va reordona coloanele din mtcars set de date în ordine inversă:
mtcars %>% select(carb:mpg)
Și următoarele vor reordona doar câteva coloane, și aruncați altele:
mtcars %>% select(mpg:disp, hp, wt, gear:qsec, starts_with('carb'))
Cititi mai multe despre dplyr's selectați sintaxa.
După cum sa menționat în acest comentariu, standard sugestii pentru re-comanda coloane într-un date.cadru` sunt, în general greoaie și predispusă la erori, mai ales dacă aveți o mulțime de coloane.
Această funcție vă permite să re-aranja coloane de poziție: specificați un nume de variabilă și poziția dorită, și don't vă faceți griji despre alte coloane.
##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)
}
Acum PO's solicite devine la fel de simplu ca acest lucru:
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
În plus swap "Timp" și "Fișiere" coloane puteți face acest lucru:
arrange.vars(table, c("Out"=2, "Files"=1, "Time"=4))
## Files Out In Time
##1 4 3 2 1
##2 5 4 3 2
Poate l's o coincidență faptul că ordinea vrei se întâmplă să aibă nume de coloană în ordine descrescătoare ordine alfabetică. Din acel's caz ai putea face:
df<-df[,order(colnames(df),decreasing=TRUE)]
Ca's de ce am folosi atunci când am fișiere de mari dimensiuni cu mai multe coloane.
Dacă puteți folosi datele.masa pachetului, atunci acest lucru oferă un bun și compact
https://stackoverflow.com/questions/12232041/how-to-reorder-data-table-columns-without-copying
setcolorder(DT,myOrder)
Trei top răspunde au o slăbiciune.
Dacă dataframe pare ca acest lucru
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
apoi se's-o soluție slabă de a utiliza
> df2[,c(1,3,2,4)]
Ea are loc de muncă, dar tocmai ați introdus-o dependență pe ordinea coloanelor în dvs. de intrare.
Acest stil de fragil de programare este de a fi evitate.
Explicit denumirea coloanelor este o soluție mai bună
data[,c("Time", "Out", "In", "Files")]
În Plus, dacă intenționați să reutilizați codul într-un cadru mai general, puteți pur și simplu
out.column.name <- "Out"
in.column.name <- "In"
data[,c("Time", out.column.name, in.column.name, "Files")]
care este, de asemenea, destul de frumos, pentru că este complet izolate de literali. Prin contrast, dacă utilizați dplyr's "selecteze"
data <- data %>% select(Time, out, In, Files)
atunci'd fi înființarea cei care vor citi codul de mai târziu, inclusiv pe tine, pentru un pic de o înșelăciune. Numele coloanelor sunt folosite ca literali, fără să apară în codul ca atare.
data.table::setcolorder(table, c("Out", "in", "files"))
Singura pe care o am văzut lucra bine este de aici.
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
}
Folosi astfel:
new_df <- iris[shuffle_columns(names(iris), "Sepal.Width before Sepal.Length")]
Funcționează ca un farmec.