Добавление столбца между двумя столбцами в файле data.frame

У меня есть кадр данных с столбцами a, b и c. Я хотел бы добавить новый столбец d между b и c. Я знаю, что могу просто добавить d в конце, используя cbind, но как я могу вставить его между двумя столбцами?

    Я предлагаю вам использовать функцию add_column() из пакета tibble .

     library(tibble) dataset <- data.frame(a = 1:5, b = 2:6, c=3:7) add_column(dataset, d = 4:8, .after = 2) 

    Обратите внимание: вы можете использовать имена столбцов вместо индекса столбца:

     add_column(dataset, d = 4:8, .after = "b") 

    Или используйте аргумент .before вместо .before если это более удобно.

     add_column(dataset, d = 4:8, .before = "c") 

    Просто новичок R, но я думаю, что это также работает:

    Добавьте в свой новый столбец:

     df$d <- list/data 

    Затем вы можете переупорядочить их.

     df <- df[,c("a","b","d","c")] 

    Вы можете изменить порядок столбцов с помощью [или представить столбцы в том порядке, в котором вы хотите.

     d <- data.frame(a=1:4, b=5:8, c=9:12) target <- which(names(d) == 'b')[1] cbind(d[,1:target,drop=F], data.frame(d=12:15), d[,(target+1):length(d),drop=F]) abdc 1 1 5 12 9 2 2 6 13 10 3 3 7 14 11 4 4 8 15 12 

    Предполагая, что c всегда сразу следует за b , этот код добавит столбец после b независимо от того, где b находится в вашем data.frame.

     > test <- data.frame(a=1,b=1,c=1) > test abc 1 1 1 1 > bspot <- which(names(test)=="b") > data.frame(test[1:bspot],d=2,test[(bspot+1):ncol(test)]) abdc 1 1 1 2 1 

    Или, возможно, более естественно:

     data.frame(append(test, list(d=2), after=match("b", names(test)))) 

    Создайте пример data.frame и добавьте в него столбец.

     df = data.frame(a = seq(1, 3), b = seq(4,6), c = seq(7,9)) df['d'] <- seq(10,12) df abcd 1 1 4 7 10 2 2 5 8 11 3 3 6 9 12 

    Переупорядочить по столбцу

     df[, colnames(df)[c(1:2,4,3)]] 

    или по имени столбца

     df[, c('a', 'b', 'd', 'c')] 

    В результате

      abdc 1 1 4 10 7 2 2 5 11 8 3 3 6 12 9 

    Вы хотите добавить столбец z в старый фрейм данных (old.df), определенный столбцами x и y.

     z = rbinom(1000, 5, 0.25) old.df <- data.frame(x = c(1:1000), y = rnorm(1:1000)) head(old.df) 

    Определите новый фрейм данных new.df

     new.df <- data.frame(x = old.df[,1], z, y = old.df[,2]) head(new.df) 

    Для чего это стоит, я написал функцию для этого:

    [Удалено]


    Я обновил эту функцию before и after функциональности и по умолчанию на 1. У нее также есть совместимость таблиц данных:

     ##### # FUNCTION: InsertDFCol(colName, colData, data, place = 1, before, after) # DESCRIPTION: Takes in a data, a vector of data, a name for that vector and a place to insert this vector into # the data frame as a new column. If you put place = 3, the new column will be in the 3rd position and push the current # 3rd column up one (and each subsuquent column up one). All arguments must be set. Adding a before and after # argument that will allow the user to say where to add the new column, before or after a particular column. # Please note that if before or after is input, it WILL override the place argument if place is given as well. Also, place # defaults to adding the new column to the front. ##### InsertDFCol <- function(colName, colData, data, place = 1, before, after) { # A check on the place argument. if (length(names(data)) < place) stop("The place argument exceeds the number of columns in the data for the InsertDFCol function. Please check your place number") if (place <= 0 & (!missing(before) | !(missing(after)))) stop("You cannot put a column into the 0th or less than 0th position. Check your place argument.") if (place %% 1 != 0 & (!missing(before) | !(missing(after)))) stop("Your place value was not an integer.") if (!(missing(before)) & !missing(after)) stop("You cannot designate a before AND an after argument in the same function call. Please use only one or the other.") # Data Table compatability. dClass <- class(data) data <- as.data.frame(data) # Creating booleans to define whether before or after is given. useBefore <- !missing(before) useAfter <- !missing(after) # If either of these are true, then we are using the before or after argument, run the following code. if (useBefore | useAfter) { # Checking the before/after argument if given. Also adding regular expressions. if (useBefore) { CheckChoice(before, names(data)) ; before <- paste0("^", before, "$") } if (useAfter) { CheckChoice(after, names(data)) ; after <- paste0("^", after, "$") } # If before or after is given, replace "place" with the appropriate number. if (useBefore) { newPlace <- grep(before, names(data)) ; if (length(newPlace) > 1) { stop("Your before argument matched with more than one column name. Do you have duplicate column names?!") }} if (useAfter) { newPlace <- grep(after, names(data)) ; if (length(newPlace) > 1) { stop("Your after argument matched with more than one column name. Do you have duplicate column names?!") }} if (useBefore) place <- newPlace # Overriding place. if (useAfter) place <- newPlace + 1 # Overriding place. } # Making the new column. data[, colName] <- colData # Finding out how to reorder this. # The if statement handles the case where place = 1. currentPlace <- length(names(data)) # Getting the place of our data (which should have been just added at the end). if (place == 1) { colOrder <- c(currentPlace, 1:(currentPlace - 1)) } else if (place == currentPlace) { # If the place to add the new data was just at the end of the data. Which is stupid...but we'll add support anyway. colOrder <- 1:currentPlace } else { # Every other case. firstHalf <- 1:(place - 1) # Finding the first half on columns that come before the insertion. secondHalf <- place:(currentPlace - 1) # Getting the second half, which comes after the insertion. colOrder <- c(firstHalf, currentPlace, secondHalf) # Putting that order together. } # Reordering the data. data <- subset(data, select = colOrder) # Data Table compatability. if (dClass[1] == "data.table") data <- as.data.table(data) # Returning. return(data) } 

    Я понял, что я также не включил CheckChoice:

     ##### # FUNCTION: CheckChoice(names, dataNames, firstWord == "Oops" message = TRUE) # DESCRIPTION: Takes the column names of a data frame and checks to make sure whatever "choice" you made (be it # your choice of dummies or your choice of chops) is actually in the data frame columns. Makes troubleshooting easier. # This function is also important in prechecking names to make sure the formula ends up being right. Use it after # adding in new data to check the "choose" options. Set firstWord to the first word you want said before an exclamation point. # The warn argument (previously message) can be set to TRUE if you only want to ##### CheckChoice <- function(names, dataNames, firstWord = "Oops", warn = FALSE) { for (name in names) { if (warn == TRUE) { if(!(name %in% dataNames)) { warning(paste0(firstWord, "! The column/value/argument, ", name, ", was not valid OR not in your data! Check your input! This is a warning message of that!")) } } if (warn == FALSE) { if(!(name %in% dataNames)) { stop(paste0(firstWord, "! The column/value/argument, " , name, ", was not valid OR not in your data! Check your input!")) } } } } 

    Вот быстрый и грязный способ вставки столбца в определенную позицию в кадре данных. В моем случае у меня есть 5 столбцов в исходном фрейме данных: c1, c2, c3, c4, c5 и я c2b новый столбец c2b между c2 и c3 .

    1) Сначала создадим кадр тестовых данных:

     > dataset <- data.frame(c1 = 1:5, c2 = 2:6, c3=3:7, c4=4:8, c5=5:9) > dataset c1 c2 c3 c4 c5 1 1 2 3 4 5 2 2 3 4 5 6 3 3 4 5 6 7 4 4 5 6 7 8 5 5 6 7 8 9 

    2) Добавьте новый столбец c2b в конец нашего фрейма данных:

     > dataset$c2b <- 10:14 > dataset c1 c2 c3 c4 c5 c2b 1 1 2 3 4 5 10 2 2 3 4 5 6 11 3 3 4 5 6 7 12 4 4 5 6 7 8 13 5 5 6 7 8 9 14 

    3) Изменить порядок кадров данных на основе индексов столбцов. В моем случае я хочу вставить новый столбец (6) между существующими столбцами 2 и 3. Я делаю это, обращаясь к столбцам в моем кадре данных, используя вектор c(1:2, 6, 3:5) который эквивалентен до c(1, 2, 6, 3, 4, 5) .

     > dataset <- dataset[,c(1:2, 6, 3:5)] > dataset c1 c2 c2b c3 c4 c5 1 1 2 10 3 4 5 2 2 3 11 4 5 6 3 3 4 12 5 6 7 4 4 5 13 6 7 8 5 5 6 14 7 8 9 

    Там!

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

     insertaCols<-function(dad){ nueva<-as.data.frame(matrix(rep(0,nrow(daf)*ncol(daf)*2 ),ncol=ncol(daf)*2)) for(k in 1:ncol(daf)){ nueva[,(k*2)-1]=daf[,k] colnames(nueva)[(k*2)-1]=colnames(daf)[k] } return(nueva) } 

    Ниже приведен пример перемещения столбца от последней до первой позиции. Он сочетает [ с ncol . Я подумал, что было бы полезно иметь очень короткий ответ здесь для занятого читателя:

     d = mtcars d[, c(ncol(d), 1:(ncol(d)-1))] 

    `

     data1 <- data.frame(col1=1:4, col2=5:8, col3=9:12) row.names(data1) <- c("row1","row2","row3","row4") data1 data2 <- data.frame(col1=21:24, col2=25:28, col3=29:32) row.names(data2) <- c("row1","row2","row3","row4") data2 insertPosition = 2 leftBlock <- unlist(data1[,1:(insertPosition-1)]) insertBlock <- unlist(data2[,1:length(data2[1,])]) rightBlock <- unlist(data1[,insertPosition:length(data1[1,])]) newData <- matrix(c(leftBlock, insertBlock, rightBlock), nrow=length(data1[,1]), byrow=FALSE) newData 

    `

    R не имеет функций, указывающих, где будет добавлен новый столбец. Например, mtcars$mycol<-'foo' . Он всегда добавляется как последний столбец. Используя другие средства (например, dplyr's select() вы можете переместить mycol в нужную позицию. Это не идеально, и R может попытаться изменить это в будущем.

    Вы можете сделать это, как показано ниже –

     df <- data.frame(a=1:4, b=5:8, c=9:12) df['d'] <- seq(10,13) df <- df[,c('a','b','d','c')] 

    Простое решение. В кадре данных с 5 столбцами, если вы хотите вставить другой столбец между 3 и 4 …

     tmp <- data[, 1:3] tmp$example <- NA # or any value. data <- cbind(tmp, data[, 4:5] 
    Давайте будем гением компьютера.