Cat*_*ine 275 sorting r dataframe r-faq
如何更改此输入(使用序列:time,in,out,files):
Time In Out Files
1 2 3 4
2 3 4 5
Run Code Online (Sandbox Code Playgroud)
到这个输出(顺序:时间,输出,文件)?
Time Out In Files
1 3 2 4
2 4 3 5
Run Code Online (Sandbox Code Playgroud)
这是虚拟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
Run Code Online (Sandbox Code Playgroud)
ric*_*roe 312
您的数据框有四列,如此df[,c(1,2,3,4)].请注意,第一个逗号表示保留所有行,1,2,3,4表示列.
要像上面的问题那样改变顺序呢 df2[,c(1,3,2,4)]
如果要将此文件作为csv输出,请执行 write.csv(df2, file="somedf.csv")
Xav*_*ola 153
# reorder by column name
data <- data[c("A", "B", "C")]
#reorder by column index
data <- data[c(1,3,2)]
Run Code Online (Sandbox Code Playgroud)
dal*_*ogm 98
您还可以使用子集函数:
data <- subset(data, select=c(3,2,1))
Run Code Online (Sandbox Code Playgroud)
您应该像在其他答案中一样更好地使用[]运算符,但知道您可以在单个命令中执行子集和列重新排序操作可能很有用.
更新:
您还可以使用dplyr包中的select函数:
data = data %>% select(Time, out, In, Files)
Run Code Online (Sandbox Code Playgroud)
我不确定效率,但是由于dplyr的语法,这个解决方案应该更灵活,特别是如果你有很多专栏.例如,以下内容将按相反顺序对mtcars数据集的列重新排序:
mtcars %>% select(carb:mpg)
Run Code Online (Sandbox Code Playgroud)
以下内容将仅对某些列重新排序,并丢弃其他列:
mtcars %>% select(mpg:disp, hp, wt, gear:qsec, starts_with('carb'))
Run Code Online (Sandbox Code Playgroud)
阅读有关dplyr的select语法的更多信息.
lan*_*oni 35
正如本评论中所提到的,在a 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)
}
Run Code Online (Sandbox Code Playgroud)
现在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
Run Code Online (Sandbox Code Playgroud)
要进一步交换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
Run Code Online (Sandbox Code Playgroud)
Ben*_*n G 29
一个dplyr解决方案是使用tidyverse:
select(table, "Time", "Out", "In", "Files")
# or
select(table, Time, Out, In, Files)
Run Code Online (Sandbox Code Playgroud)
use*_*899 24
也许巧合的是,您想要的列顺序恰好按字母顺序降序排列.既然如此,你可以做到:
df<-df[,order(colnames(df),decreasing=TRUE)]
Run Code Online (Sandbox Code Playgroud)
这就是我使用包含许多列的大文件时使用的内容.
H 1*_*H 1 23
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)
Run Code Online (Sandbox Code Playgroud)
或者
dat %>%
relocate(Out, .after = Time)
Run Code Online (Sandbox Code Playgroud)
usc*_*t01 16
如果你可以使用data.table包,那么这提供了一种良好而紧凑的方式
setcolorder(DT,myOrder)
Run Code Online (Sandbox Code Playgroud)
Vro*_*pal 10
如果您的数据框看起来像这样
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
Run Code Online (Sandbox Code Playgroud)
那就不好用了
> df2[,c(1,3,2,4)]
Run Code Online (Sandbox Code Playgroud)
它可以完成工作,但是您刚刚引入了对输入中列顺序的依赖性。
应避免这种脆性编程风格。
列的明确命名是更好的解决方案
data[,c("Time", "Out", "In", "Files")]
Run Code Online (Sandbox Code Playgroud)
另外,如果您打算在更一般的设置中重用代码,则只需
out.column.name <- "Out"
in.column.name <- "In"
data[,c("Time", out.column.name, in.column.name, "Files")]
Run Code Online (Sandbox Code Playgroud)
这也很好,因为它完全隔离了文字。相反,如果您使用dplyrselect
data <- data %>% select(Time, out, In, Files)
Run Code Online (Sandbox Code Playgroud)
那么您将设置那些稍后将阅读您的代码(包括您自己)的人,以免造成欺骗。列名被用作文字,而没有出现在代码中。