重新排序大型数据框中的列

时间:2013-08-20 15:42:30

标签: r

使用以下示例数据框:

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后的列? (仅引用我要移动的列或列范围?)。

非常感谢您的帮助。

8 个答案:

答案 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.0df %>% 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] )