Как можно изменить этот вход (с последовательностью: время, вход, выход, файлы):
Time In Out Files
1 2 3 4
2 3 4 5
на этот выход (с последовательностью: time, out, in, files)?
Time Out In Files
1 3 2 4
2 4 3 5
Вот фиктивные данные 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
Ваш датафрейм имеет четыре столбца, например, так df[,c(1,2,3,4)]
.
Обратите внимание, что первая запятая означает сохранение всех строк, а 1,2,3,4 относятся к столбцам.
Чтобы изменить порядок, как в приведенном выше вопросе, сделайте df2[,c(1,3,2,4)]
.
Если вы хотите вывести этот файл в формате csv, выполните команду 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)]
Вы также можете использовать функцию подмножества:
data <- subset(data, select=c(3,2,1))
Лучше использовать оператор [], как в других ответах, но может быть полезно знать, что вы можете выполнить операцию подмножества и переупорядочения столбцов в одной команде.
Обновление:
Вы также можете использовать функцию select из пакета dplyr:
data = data %>% select(Time, out, In, Files)
Я не уверен в эффективности, но благодаря синтаксису dplyr'а это решение должно быть более гибким, особенно если у вас много столбцов. Например, в следующем примере столбцы набора данных mtcars будут упорядочены в обратном порядке:
mtcars %>% select(carb:mpg)
А следующий вариант переупорядочит только некоторые столбцы и отбросит другие:
mtcars %>% select(mpg:disp, hp, wt, gear:qsec, starts_with('carb'))
Подробнее о dplyr's select syntax.
Как отмечалось в этот комментарий, стандартные предложения на изменение порядка столбцов в данных.каркас, как правило, громоздким и подвержен ошибкам, особенно если у вас много столбцов.
Эта функция позволяет упорядочить столбцы по позиции: указать имя переменной и желаемую должность, и Дон'т беспокоиться о других столбцов.
##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)
}
Сейчас ОП's запрос становится таким же простым, как это:
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
Дополнительно своп время
и файлы
столбцов, вы можете сделать это:
arrange.vars(table, c("Out"=2, "Files"=1, "Time"=4))
## Files Out In Time
##1 4 3 2 1
##2 5 4 3 2
Может быть, это's не случайно, что порядок столбцов вы хотите, есть имена столбцов в алфавитном порядке по убыванию. Так что's в случае, если вы могли бы просто сделать:
df<-df[,order(colnames(df),decreasing=TRUE)]
Что's я использую, когда у меня большие файлы с большим количеством столбцов.
Если вы можете использовать данные.пакет таблицы, то это обеспечивает хороший и компактный способ
https://stackoverflow.com/questions/12232041/how-to-reorder-data-table-columns-without-copying
setcolorder(DT,myOrder)
Три Лучшие Ответы есть слабости.
Если ваши таблицы данных выглядит так
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
потом он'с плохим разрешением, чтобы использовать
> df2[,c(1,3,2,4)]
Это делает работу, но вы только что ввели зависимость от порядка столбцов во входном.
Этот стиль хрупкого программирования следует избегать.
Явного именования столбцов-это лучшее решение
data[,c("Time", "Out", "In", "Files")]
Плюс, если вы намерены повторно использовать ваш код в более общем случае, вы можете просто
out.column.name <- "Out"
in.column.name <- "In"
data[,c("Time", out.column.name, in.column.name, "Files")]
что тоже довольно приятно, потому что он полностью изолирует литералы. Напротив, если использовать dplyr'ы выберите
data <- data %>% select(Time, out, In, Files)
затем вы'd быть настройка тех, кто будет читать ваш код позже, включая вас, немного обмана. Имена столбцов используются как литералы, не появляться в код как таковой.
data.table::setcolorder(table, c("Out", "in", "files"))
Единственный, кого я видел, хорошо работают от ЗДЕСЬ.
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
}
Использовать такой:
new_df <- iris[shuffle_columns(names(iris), "Sepal.Width before Sepal.Length")]
Работает как шарм.