Перемещение столбцов внутри data.frame () без повторного ввода - PullRequest
52 голосов
/ 30 июля 2010

Существует ли способ перемещения столбца из одной позиции в data.frame на следующую - без ввода совершенно нового data.frame ()

Например:

a <- b <- c <- d <- e <- f <- g <- 1:100
df <- data.frame(a,b,c,d,e,f,g)

Теперь допустим, что я хотел "g" перед "a"

Я мог бы перепечатать его, как

df <- data.frame(g,a,b,c,d,e,f)

Но нет ли более быстрого пути? (Представьте 1500+ столбцов)

Ответы [ 15 ]

0 голосов
/ 26 января 2018

Вот простая, но гибкая функция, которую я написал для перемещения столбца в любом месте фрейма данных.

move.col <- function(df, move_this, next_to_this, before = FALSE) {
  if (before==FALSE)
    df[,c(match(setdiff(names(df)[1:which(names(df)==next_to_this)],move_this),names(df)),
          match(move_this,names(df)),
          match(setdiff(names(df)[which(names(df)==next_to_this):ncol(df)],c(next_to_this,move_this)),names(df)))]
  else
    df[,c(match(setdiff(names(df)[1:(which(names(df)==next_to_this))],c(next_to_this,move_this)),names(df)),
          match(move_this,names(df)),
          match(setdiff(names(df)[(which(names(df)==next_to_this)):ncol(df)],move_this),names(df)))]
}

Использование: Укажите фрейм данных (df), имя столбца, который вы хотите переместить (move_this), и имя столбца, который вы хотите переместитьрядом (next_to_this).По умолчанию функция будет перемещать столбец move_this после столбца next_to_this.Вы можете указать before = TRUE для перемещения move_this до next_to_this.

Примеры:

  1. Переместить «b» после «g» (т. Е.сделать последний столбец "b").

move.col(df, "b", "g")

Переместите «c» после «e».

move.col(df, "c", "e")

Переместите «g» перед «a» (т. Е. Сделайте «g» первым столбцом).

move.col(df, "g", "a", before=TRUE)

Переместите «d» и «f» перед «b» (т. Е. Переместите несколько столбцов).

move.col(df,c("d","f"),"b", before=TRUE)

0 голосов
/ 22 февраля 2017

Я хотел бы предложить другой универсальный рабочий подход, аналогичный предыдущим ответам Р.С. Мануэля и Скотта Кайзера, который работает только в определенных случаях:

move<-function(new.pos,nameofcolumn,dfname) {
  col_idx <- grep(nameofcolumn, names(dfname))
  if (length(col_idx)==0){print("invalid column name");return(dfname)} else {
  if(new.pos>ncol(dfname)){print("invalid column number");return(dfname)} else {
  if (new.pos==1) {
    b<-dfname[ , c( col_idx, c((new.pos):ncol(dfname))[-(abs(new.pos-1-col_idx))] )]  
    }
  else if(col_idx==1 & new.pos==ncol(dfname)){
    b<-dfname[ , c((1:(new.pos-1)+1), col_idx )] 
    }
  else if(col_idx==1){
    b<-dfname[ , c((1:(new.pos-1)+1), col_idx, c((new.pos+1):ncol(dfname)) )] 
    }
  else if(new.pos==ncol(dfname)){
    b<-dfname[ , c((1:(new.pos))[-col_idx], col_idx)] 
    }
  else if(new.pos>col_idx){
    b<-dfname[ , c((1:(new.pos))[-col_idx], col_idx, c((new.pos+1):ncol(dfname)) )] 
    } 
  else{
    b<-dfname[ , c((1:(new.pos-1)), col_idx, c((new.pos):ncol(dfname))[-(abs(new.pos-1-col_idx))] )]
    }
  return(b)
  if(length(ncol(b))!=length(ncol(dfname))){print("error")}
  }
}}

Использование:

a <- b <- c <- d <- e <- f <- g <- 1:5
df <- data.frame(a,b,c,d,e,f,g)
move(1,"g",df)
0 голосов
/ 08 ноября 2016

Вот одна функция, которая может помочь

  • df : фрейм данных
  • ColName : имя столбца (с)) для перемещения
  • Позиция : номер столбца, для которого должен отображаться перемещенный столбец

moveCol <- function(df,ColName,Position=1) {
    D <- dim(df)[2]
    DFnames <- names(df)
    if (Position>D+1 | Position<1) {
        warning(paste0('Column position ',sprintf('%d',Position), ' is out of range [1-',sprintf('%d',D),']'))
        return()
    }
    for (i in ColName) {
        x <- i==DFnames
        if (all(!x)) {
            warning(paste0('Column \"', i, '\" not found'))
        } else {
            D1 <- seq(D)
            D1[x] = Position - 0.5
            df<- df[order(D1)]
        }
    }
    return(df)
}
0 голосов
/ 18 марта 2016

@ Дэвид спросил, как переместить «G» в произвольную позицию, например 4. Опираясь на ответ @rcs,

new.pos <- 4
col_idx <- grep("g", names(df))
df      <- df[ , c((1:new.pos)[-col_idx], col_idx, c((new.pos):ncol(df))[-col_idx])]
0 голосов
/ 23 декабря 2015

Если переупорядочение является сменой, как в вашем примере, вы можете использовать функцию shift из пакета taRifx. Он действует на векторы, поэтому применяется к именам столбцов:

> a <- b <- c <- d <- e <- f <- g <- 1:5
> df <- data.frame(a,b,c,d,e,f,g)
> df[, taRifx::shift(seq_along(df),-1)]
  g a b c d e f
1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5

Фактически функция shift также может применяться к фрейму данных, но не так, как ожидалось. Вы можете написать функцию:

> shift_df <- function(df, n) df[, taRifx::shift(seq_along(df),n)]
> shift_df(df, -1)
  g a b c d e f
1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5
> shift_df(df, 2)
  c d e f g a b
1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...