如何改变这个输入(顺序:时间,输入,输出,文件):
Time In Out Files
1 2 3 4
2 3 4 5
到这个输出(序列:时间,输出,输入,文件)?
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
Dplyr有一个函数,允许您将特定列移动到其他列的前面或后面。当您使用大数据框架时,这是一个关键的工具(如果是4列,使用前面提到的select更快)。
https://dplyr.tidyverse.org/reference/relocate.html
在你的情况下,它将是:
df <- df %>% relocate(Out, .after = In)
简单而优雅。它还允许你一起移动几列,并将其移动到开始或结束:
df <- df %>% relocate(any_of(c('ColX', 'ColY', 'ColZ')), .after = last_col())
再次强调:当你使用大数据框架时,超级强大:)
得分最高的三个答案都有一个弱点。
如果数据帧是这样的
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的select
data <- data %>% select(Time, 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")]
效果非常好。
Dplyr有一个函数,允许您将特定列移动到其他列的前面或后面。当您使用大数据框架时,这是一个关键的工具(如果是4列,使用前面提到的select更快)。
https://dplyr.tidyverse.org/reference/relocate.html
在你的情况下,它将是:
df <- df %>% relocate(Out, .after = In)
简单而优雅。它还允许你一起移动几列,并将其移动到开始或结束:
df <- df %>% relocate(any_of(c('ColX', 'ColY', 'ColZ')), .after = last_col())
再次强调:当你使用大数据框架时,超级强大:)
一个dplyr解决方案(tidyverse包集的一部分)是使用select:
select(table, "Time", "Out", "In", "Files")
# or
select(table, Time, Out, In, Files)