data.frame의 두 열 사이에 열 추가 (삽입)


87

a, b 및 c 열이있는 데이터 프레임이 있습니다. b와 c 사이에 새 열 d를 추가하고 싶습니다.

cbind 를 사용하여 끝에 d를 추가 할 수 있다는 것을 알고 있지만 두 열 사이에 어떻게 삽입 할 수 있습니까?


어쩌면 이것은 당신이 원하는 것을 : r.789695.n4.nabble.com/...
마크 밀러

1
dplyr 패키지의 mutate () 함수는이 질문에 명시된대로 열을 추가 할 수 있습니까?
marbel

답변:


81

난 당신이 기능을 사용하는 것이 좋습니다 것입니다 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대신 인수 를 사용하십시오 .after.

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

6
이름이 떨어지는 것을 제거했습니다. 많이 추가하지 않는 것, 그리고 해들리는 다음과 같이 나열되는 동안 패키지 키릴 뮐러의 저자로 표시됩니다 창조자와 메인테이너 .
Gregor Thomas

38

새 열에 추가하십시오.

df$d <- list/data

그런 다음 다시 정렬 할 수 있습니다.

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

1
setcolorder열 번호 (이름이 아닌)와 함께 사용 하는 재정렬 도 매우 유용하다는 것을 알게 되었습니다. 열 수가 매우 많아지면 사용을 시작 seq하고 rep대부분의 작업을 수행 할 수 있기 때문 입니다. 또한 산술 연산자를 사용할 수 있습니다. 예setcolorder(data, c(1, (num_cols -2), (num_cols -1), num_cols, seq(from = 2, to = (num_cols - 3))))
n1k31t4

1
언급해야 setcolorder할 것은 data.frame이 아니라 data.table을 의미합니다!
n1k31t4

21

[를 사용하여 열을 재정렬하거나 원하는 순서로 열을 표시 할 수 있습니다.

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])

  a b  d  c
1 1 5 12  9
2 2 6 13 10
3 3 7 14 11
4 4 8 15 12

13
이것은 훌륭한 대답입니다. 하지만 저는 인정해야합니다. 이것은 R이 초보자에게 왜 어려울 수 있는지에 대한 좋은 예입니다.
tumultous_rooster 2013

2
즉, @ ashah57이 아래에 훨씬 더 간단하고 깨끗한 대답이 있다고 생각합니다. 이와 같은 것에 너무 화려할 필요가 없습니다.
tumultous_rooster

12

c항상 바로 다음에 오는 것으로 가정하면 b이 코드는 data.frame의 b위치 b에 관계없이 뒤에 열을 추가합니다 .

> test <- data.frame(a=1,b=1,c=1)
> test
  a b c
1 1 1 1

> bspot <- which(names(test)=="b")

> data.frame(test[1:bspot],d=2,test[(bspot+1):ncol(test)])
  a b d c
1 1 1 2 1

또는 더 자연스럽게 :

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

5

예제 data.frame을 만들고 여기에 열을 추가합니다.

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

  a b c  d
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')]

결과는

  a b  d c
1 1 4 10 7
2 2 5 11 8
3 3 6 12 9

3

열 x와 y로 정의 된 이전 데이터 프레임 (old.df)에 z 열을 추가하려고합니다.

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)

2

다음은 데이터 프레임의 특정 위치에 열을 삽입하는 빠르고 더러운 방법입니다. 내 경우, 나는 원래 데이터 프레임에서 5 열이 : c1, c2, c3, c4, c5나는 새 열을 삽입합니다 c2b사이 c2c3.

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) 컬럼 인덱스를 기반으로 데이터 프레임을 재정렬하십시오. 제 경우 제가 벡터하여 내 데이터 프레임의 열을 어드레싱하여 그 열을 기존의 2와 3 사이에 새로운 열 (6)에 삽입 할 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

그곳에!


2

그만한 가치를 위해 다음과 같은 함수를 작성했습니다.

[삭제됨]


이제이 함수를 beforeafter기능으로 업데이트 하고 기본값 place을 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!")) } }

  }
}

2

쉬운 솔루션. 5 개의 열이있는 데이터 프레임에서 3과 4 사이에 다른 열을 삽입하려면 ...

tmp <- data[, 1:3]
tmp$example <- NA # or any value.
data <- cbind(tmp, data[, 4:5]

1

이 함수는 데이터 프레임의 모든 기존 열 사이에 하나의 0 열을 삽입합니다.

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)   
  }

1

다음은 마지막 위치에서 첫 번째 위치로 열을 이동하는 방법의 예입니다. 이 결합 [으로 ncol. 바쁜 독자를 위해 여기에 매우 짧은 대답을하는 것이 유용 할 것이라고 생각했습니다.

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

1

append()함수를 사용하여 벡터 또는 목록에 항목을 삽입 할 수 있습니다 (데이터 프레임은 목록 임). 간단히:

df <- data.frame(a=c(1,2), b=c(3,4), c=c(5,6))

df <- as.data.frame(append(df, list(d=df$b+df$c), after=2))

또는 이름으로 위치를 지정하려면 which다음을 사용하십시오 .

df <- as.data.frame(append(df, list(d=df$b+df$c), after=which(names(df)=="b")))

0

`

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

`


0

R에는 새 열이 추가되는 위치를 지정하는 기능이 없습니다. 예 : mtcars$mycol<-'foo'. 항상 마지막 열로 추가됩니다. 다른 방법 (예 dplyr's select():)을 사용하여 mycol을 원하는 위치로 이동할 수 있습니다. 이것은 이상적이지 않으며 R은 미래에 그것을 변경하려고 할 수 있습니다.


예, append기능이 있습니다.
사이먼 우드워드

0

아래와 같이 할 수 있습니다-

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

0
df <- data.frame(a=c(1,2), b=c(3,4), c=c(5,6))
df %>%
  mutate(d= a/2) %>%
  select(a, b, d, c)

결과

  a b   d c
1 1 3 0.5 5
2 2 4 1.0 6

나는 dplyr::select후에 사용하는 것이 좋습니다 dplyr::mutate. 열의 하위 집합을 선택 / 선택 취소하는 많은 도우미가 있습니다.

이 질문의 맥락에서 선택한 순서는 출력 data.frame에 반영됩니다.


0

b이 더 낮은 열 번호를 얻고이 열 까지 시퀀스를 얻기 위해 둘 다의 열 번호를 찾는 데 c사용할 수 있기 전에 열 이 온다고 가정 할 수 없습니다 . 그런 다음 새 열을 배치 한 다음 시퀀스를 다시 음의 하위 집합 으로 사용하는 것보다 먼저이 인덱스를 양의 하위 집합 으로 사용할 수 있습니다 .matchminseq_lend

i <- seq_len(min(match(c("b", "c"), colnames(x))))
data.frame(x[i], d, x[-i])
#cbind(x[i], d, x[-i]) #Alternative
#  a b  d c
#1 1 4 10 7
#2 2 5 11 8
#3 3 6 12 9

b이 나오기 전에 c새 열 d을 배치 할 수 있다는 것을 알고있는 경우 b:

i <- seq_len(match("b", colnames(x)))
data.frame(x[i], d, x[-i])
#  a b  d c
#1 1 4 10 7
#2 2 5 11 8
#3 3 6 12 9

데이터:

x <- data.frame(a = 1:3, b = 4:6, c = 7:9)
d <- 10:12
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.