使用以下示例数据框:
a <- c(1:5)
b <- c("Cat", "Dog", "Rabbit", "Cat", "Dog")
c <- c("Dog", "Rabbit", "Cat", "Dog", "Dog")
d <- c("Rabbit", "Cat", "Dog", "Dog", "Rabbit")
e <- c("Cat", "Dog", "Dog", "Rabbit", "Cat")
f <- c("Cat", "Dog", "Dog", "Rabbit", "Cat")
df <- data.frame(a,b,c,d,e,f)
我想研究如何重新排序列,而不必输入所有列名,即df[,c("a","d","e","f","b","c")]
我怎么说我想要列f和列f后的列? (仅引用我要移动的列或列范围?)。
非常感谢您的帮助。
答案 0 :(得分:37)
要将特定列移至data.frame的开头或结尾,请使用dplyr包及其select
函数中的everything()
。在这个例子中,我们发送到最后:
library(dplyr)
df %>%
select(-b, -c, everything())
a d e f b c
1 1 Rabbit Cat Cat Cat Dog
2 2 Cat Dog Dog Dog Rabbit
3 3 Dog Dog Dog Rabbit Cat
4 4 Dog Rabbit Rabbit Cat Dog
5 5 Rabbit Cat Cat Dog Dog
没有否定,列将被发送到前面。
答案 1 :(得分:29)
如果你只是将某些列移到最后,你可以创建一个小帮助函数,如下所示:
movetolast <- function(data, move) {
data[c(setdiff(names(data), move), move)]
}
movetolast(df, c("b", "c"))
# a d e f b c
# 1 1 Rabbit Cat Cat Cat Dog
# 2 2 Cat Dog Dog Dog Rabbit
# 3 3 Dog Dog Dog Rabbit Cat
# 4 4 Dog Rabbit Rabbit Cat Dog
# 5 5 Rabbit Cat Cat Dog Dog
我不建议过于习惯使用列位置,特别是不是从程序角度来看,因为这些位置可能会发生变化。
以下是对上述功能的扩展解释。它允许您将列移动到第一个或最后一个位置,或者移动到另一个列之前或之后。
moveMe <- function(data, tomove, where = "last", ba = NULL) {
temp <- setdiff(names(data), tomove)
x <- switch(
where,
first = data[c(tomove, temp)],
last = data[c(temp, tomove)],
before = {
if (is.null(ba)) stop("must specify ba column")
if (length(ba) > 1) stop("ba must be a single character string")
data[append(temp, values = tomove, after = (match(ba, temp)-1))]
},
after = {
if (is.null(ba)) stop("must specify ba column")
if (length(ba) > 1) stop("ba must be a single character string")
data[append(temp, values = tomove, after = (match(ba, temp)))]
})
x
}
请尝试以下操作。
moveMe(df, c("b", "c"))
moveMe(df, c("b", "c"), "first")
moveMe(df, c("b", "c"), "before", "e")
moveMe(df, c("b", "c"), "after", "e")
你需要调整它以进行一些错误检查 - 例如,如果你试图将列“b”和“c”移到“c之前”,你(显然)会得到一个错误。 / p>
答案 2 :(得分:12)
您可以按位置引用列。 e.g。
df <- df[ ,c(1,4:6,2:3)]
> df
a d e f b c
1 1 Rabbit Cat Cat Cat Dog
2 2 Cat Dog Dog Dog Rabbit
3 3 Dog Dog Dog Rabbit Cat
4 4 Dog Rabbit Rabbit Cat Dog
5 5 Rabbit Cat Cat Dog Dog
答案 3 :(得分:3)
使用dplyr
来概括以任何顺序重新排列列,例如,重新洗牌:
df <- data.frame(a,b,c,d,e,f)
到
df[,c("a","d","e","f","b","c")]
df %>% select(a, d:f, b:c)
答案 4 :(得分:2)
使用子集功能:
> df <- data.frame(a,b,c,d,e,f)
> df <- subset(df, select = c(a, d:f, b:c))
> df
a d e f b c
1 1 Rabbit Cat Cat Cat Dog
2 2 Cat Dog Dog Dog Rabbit
3 3 Dog Dog Dog Rabbit Cat
4 4 Dog Rabbit Rabbit Cat Dog
5 5 Rabbit Cat Cat Dog Dog
答案 5 :(得分:2)
包dplyr::relocate
和函数dplyr 1.0.0
(df %>% dplyr::relocate(b, c, .after = f)
中引入的新动词)完全满足您的需求。
ReadOnlySpan<byte>
答案 6 :(得分:1)
我更改了上一个函数,将其用于data.table,用于包data.table的函数setcolorder。
moveMeDataTable <-function(data, tomove, where = "last", ba = NULL) {
temp <- setdiff(names(data), tomove)
x <- switch(
where,
first = setcolorder(data,c(tomove, temp)),
last = setcolorder(data,c(temp, tomove)),
before = {
if (is.null(ba)) stop("must specify ba column")
if (length(ba) > 1) stop("ba must be a single character string")
order = append(temp, values = tomove, after = (match(ba, temp)-1))
setcolorder(data,order)
},
after = {
if (is.null(ba)) stop("must specify ba column")
if (length(ba) > 1) stop("ba must be a single character string")
order = append(temp, values = tomove, after = (match(ba, temp)))
setcolorder(data,order)
})
x
}
DT <- data.table(A=sample(3, 10, TRUE),
B=sample(letters[1:3], 10, TRUE), C=sample(10))
DT <- moveMeDataTable(DT, "C", "after", "A")
答案 7 :(得分:0)
这是另一种选择:
df <- cbind( df[, -(2:3)], df[, 2:3] )