如何更改此输入(使用序列:time,in,out,files):
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
答案 0 :(得分:280)
您的数据框有四列,如df[,c(1,2,3,4)]
。
请注意,第一个逗号表示保留所有行,1,2,3,4表示列。
要更改上述问题,请执行df2[,c(1,3,2,4)]
如果要将此文件作为csv输出,请执行write.csv(df2, file="somedf.csv")
答案 1 :(得分:139)
# reorder by column name
data <- data[c("A", "B", "C")]
#reorder by column index
data <- data[c(1,3,2)]
答案 2 :(得分:84)
您还可以使用子集函数:
data <- subset(data, select=c(3,2,1))
您应该在其他答案中更好地使用[]运算符,但知道您可以在单个命令中执行子集和列重新排序操作可能很有用。
更新
您也可以使用dplyr包中的select函数:
data = data %>% select(Time, out, In, Files)
我不确定效率,但是由于dplyr的语法,这个解决方案应该更灵活,特别是如果你有很多专栏。例如,以下内容将按相反的顺序对mtcars数据集的列重新排序:
mtcars %>% select(carb:mpg)
以下内容将仅对某些列重新排序,并丢弃其他列:
mtcars %>% select(mpg:disp, hp, wt, gear:qsec, starts_with('carb'))
答案 3 :(得分:33)
正如this comment中所述,在data.frame
中重新排序列的标准建议通常很麻烦且容易出错,尤其是如果您有很多列。
此功能允许按位置重新排列列:指定变量名称和所需位置,而不必担心其他列。
##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)
}
现在OP的请求变得如此简单:
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
要另外交换Time
和Files
列,您可以执行此操作:
arrange.vars(table, c("Out"=2, "Files"=1, "Time"=4))
## Files Out In Time
##1 4 3 2 1
##2 5 4 3 2
答案 4 :(得分:24)
这可能是一个巧合,您想要的列顺序恰好按字母顺序降序排列。既然如此,你可以做到:
df<-df[,order(colnames(df),decreasing=TRUE)]
当我拥有包含许多列的大型文件时,我使用的是什么。
答案 5 :(得分:15)
如果你可以使用data.table包,那么这提供了一种良好而紧凑的方式
How to reorder data.table columns (without copying)
setcolorder(DT,myOrder)
答案 6 :(得分:14)
select
解决方案是使用select(table, "Time", "Out", "In", "Files")
# or
select(table, Time, Out, In, Files)
:
{{1}}
答案 7 :(得分:9)
dplyr
版本1.0.0
包含relocate()
函数,可轻松对列进行重新排序:
dat <- data.frame(Time=c(1,2), In=c(2,3), Out=c(3,4), Files=c(4,5))
library(dplyr) # from version 1.0.0 only
dat %>%
relocate(Out, .before = In)
或
dat %>%
relocate(Out, .after = Time)
答案 8 :(得分:6)
如果您的数据框看起来像这样
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&#39; s select
data <- data %>% select(Time, out, In, Files)
然后你会设置那些稍后会自己阅读你的代码的人,包括你自己的一些欺骗行为。列名被用作文字而不会出现在代码中。
答案 9 :(得分:1)
我见过的唯一一个效果很好的是来自here。
from collections import defaultdict
class TrieNode:
def __init__(self):
self.children = defaultdict(TrieNode)
self.isEnd = False
def insert(self, word):
node = self
for w in word:
node = node.children[w]
node.isEnd = True
def find_prefix(self, prefix, result):
if self.isEnd:
result.append(prefix[:])
return
for k,v in self.children.items():
prefix.append(k)
v.find_prefix(prefix, result)
prefix.pop(-1)
if __name__ == "__main__":
words = ['foo', 'foog', 'food', 'asdf']
root = TrieNode()
for w in words:
root.insert(w)
result = []
root.find_prefix([], result)
print result
像这样使用:
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
}
像魅力一样工作。
答案 10 :(得分:1)
setcolorder(table, c("Out", "in", "files"))