원래 행 순서를 유지하면서 두 데이터 프레임 병합
두 데이터 프레임 중 하나의 원래 행 순서를 유지하면서 두 데이터 프레임을 병합하고 싶습니다 ( df.2
아래 예 참조).
다음은 몇 가지 샘플 데이터입니다 ( class
열의 모든 값 이 두 데이터 프레임 모두에 정의 됨).
df.1 <- data.frame(class = c(1, 2, 3), prob = c(0.5, 0.7, 0.3))
df.2 <- data.frame(object = c('A', 'B', 'D', 'F', 'C'), class = c(2, 1, 2, 3, 1))
만약 내가한다면:
merge(df.2, df.1)
출력은 다음과 같습니다.
class object prob
1 1 B 0.5
2 1 C 0.5
3 2 A 0.7
4 2 D 0.7
5 3 F 0.3
내가 추가하면 sort = FALSE
:
merge(df.2, df.1, sort = F)
결과는 다음과 같습니다.
class object prob
1 2 A 0.7
2 2 D 0.7
3 1 B 0.5
4 1 C 0.5
5 3 F 0.3
하지만 내가 원하는 것은 :
class object prob
1 2 A 0.7
2 1 B 0.5
3 2 D 0.7
4 3 F 0.3
5 1 C 0.5
플라이어 패키지의 결합 기능을 확인하십시오. 병합과 비슷하지만 데이터 세트 중 하나의 행 순서를 유지할 수 있습니다. 전반적으로 병합보다 더 유연합니다.
예제 데이터를 사용하여 다음 join
과 같이 사용 합니다.
> join(df.2,df.1)
Joining by: class
object class prob
1 A 2 0.7
2 B 1 0.5
3 D 2 0.7
4 F 3 0.3
5 C 1 0.5
다음은 행 순서를 유지하기 위해 병합 기능에 대한 수정 사항을 설명하는 몇 가지 링크입니다.
http://www.r-statistics.com/2012/01/merging-two-data-frame-objects-while-preserving-the-rows-order/
df.2에서 행 번호를 제공하는 변수를 생성하기 만하면됩니다. 그런 다음 데이터를 병합하면이 변수에 따라 새 데이터 세트를 정렬합니다. 다음은 예입니다.
df.1<-data.frame(class=c(1,2,3), prob=c(0.5,0.7,0.3))
df.2<-data.frame(object=c('A','B','D','F','C'), class=c(2,1,2,3,1))
df.2$id <- 1:nrow(df.2)
out <- merge(df.2,df.1, by = "class")
out[order(out$id), ]
에서 data.table v1.9.5의 + , 당신은 할 수 있습니다 :
require(data.table) # v1.9.5+
setDT(df.1)[df.2, on="class"]
는 각 행에 대해 class
일치하는 행을 찾고 해당 열을 추출 하여 열에 대해 조인을 수행합니다 .df.1
df.2
inner_join
Hadley의 dplyr
패키지 (다음 반복 plyr
) 에서 함수를 확인할 수도 있습니다 . 첫 번째 데이터 세트의 행 순서를 유지합니다. 원하는 솔루션의 사소한 차이점은 첫 번째 데이터 세트의 원래 열 순서도 유지한다는 것입니다. 따라서 병합에 사용한 열이 반드시 첫 번째 위치에 배치되는 것은 아닙니다.
위의 예를 사용하면 inner_join
결과는 다음과 같습니다.
inner_join(df.2,df.1)
Joining by: "class"
object class prob
1 A 2 0.7
2 B 1 0.5
3 D 2 0.7
4 F 3 0.3
5 C 1 0.5
완전성을 위해 조인에서 업데이트 하면 원래 행 순서도 유지됩니다. 추가 할 열이 몇 개 뿐인 경우 Arun의 data.table
답변에 대한 대안이 될 수 있습니다 .
library(data.table)
setDT(df.2)[df.1, on = "class", prob := i.prob][]
object class prob 1: A 2 0.7 2: B 1 0.5 3: D 2 0.7 4: F 3 0.3 5: C 1 0.5
여기서는, df.2
오른쪽으로 접합되어 df.1
새로운 컬럼 얻는다 prob
의 매칭되는 열에서 복사된다 df.1
.
허용 대답은 사용하기 위해 유지하는 수동 방식으로 제시 merge
대부분의 시간을 작동하지만 불필요한 수작업을 필요로하는가. 이 솔루션은 정렬하지 않고 ddply ()하는 방법 의 뒷면에 있습니다 . , 순서 유지 문제를 처리하지만 분할 적용 결합 컨텍스트 :
이것은 잠시 전에 plyr 메일 링리스트에 올라 왔고 (@kohske에 의해 제기 됨) 이것은 제한된 경우에 대해 Peter Meilstrup이 제공 한 솔루션입니다.
#Peter's version used a function gensym to
# create the col name, but I couldn't track down
# what package it was in.
keeping.order <- function(data, fn, ...) {
col <- ".sortColumn"
data[,col] <- 1:nrow(data)
out <- fn(data, ...)
if (!col %in% colnames(out)) stop("Ordering column not preserved by function")
out <- out[order(out[,col]),]
out[,col] <- NULL
out
}
이제이 일반 keeping.order
함수를 사용 하여 merge
호출 의 원래 행 순서를 유지할 수 있습니다 .
df.1<-data.frame(class=c(1,2,3), prob=c(0.5,0.7,0.3))
df.2<-data.frame(object=c('A','B','D','F','C'), class=c(2,1,2,3,1))
keeping.order(df.2, merge, y=df.1, by = "class")
요청에 따라 다음과 같이 산출됩니다.
> keeping.order(df.2, merge, y=df.1, by = "class")
class object id prob
3 2 A 1 0.7
1 1 B 2 0.5
4 2 D 3 0.7
5 3 F 4 0.3
2 1 C 5 0.5
따라서 keeping.order
수용된 답변의 접근 방식을 효과적으로 자동화합니다.
@PAC 덕분에 다음과 같은 결과를 얻었습니다.
merge_sameord = function(x, y, ...) {
UseMethod('merge_sameord')
}
merge_sameord.data.frame = function(x, y, ...) {
rstr = paste(sample(c(0:9, letters, LETTERS), 12, replace=TRUE), collapse='')
x[, rstr] = 1:nrow(x)
res = merge(x, y, all.x=TRUE, sort=FALSE, ...)
res = res[order(res[, rstr]), ]
res[, rstr] = NULL
res
}
이는 첫 번째 데이터 프레임의 순서를 유지하고 병합 된 데이터 프레임의 행 수가 첫 번째 데이터 프레임과 동일하다고 가정합니다. 추가 열없이 깨끗한 데이터 프레임을 제공합니다.
이 특별한 경우 factor
에는 컴팩트 한 기본 솔루션을 제공 할 수 있습니다.
df.2$prob = factor(df.2$class,labels=df.1$prob)
df.2
# object class prob
# 1 A 2 0.7
# 2 B 1 0.5
# 3 D 2 0.7
# 4 F 3 0.3
# 5 C 1 0.5
그러나 일반적인 솔루션은 아니지만 다음과 같은 경우 작동합니다.
- 고유 한 값이 포함 된 조회 테이블이 있습니다.
- 테이블을 새로 만들지 않고 업데이트하려고합니다.
- 조회 테이블은 병합 열을 기준으로 정렬됩니다.
- 조회 테이블에는 추가 수준이 없습니다.
- 당신은
left_join
- 요인이 괜찮다면
1은 협상 할 수 없으며 나머지는 다음과 같이 할 수 있습니다.
df.3 <- df.2 # deal with 2.
df.1b <- df.1[order(df.1$class),] # deal with 3
df.1b <- df.1b[df.1$class %in% df.2$class,] # deal with 4.
df.3$prob = factor(df.3$class,labels=df.1b$prob)
df.3 <- df3[!is.na(df.3$prob),] # deal with 5. if you want an `inner join`
df.3$prob <- as.numeric(as.character(df.3$prob)) # deal with 6.
간단한 하위 집합이 수행하는 몇 가지 사용 사례가 있습니다.
# Use the key variable as row.names
row.names(df.1) = df.1$key
# Sort df.1 so that it's rows match df.2
df.3 = df.1[df.2$key, ]
# Create a data.frame with cariables from df.1 and (the sorted) df.2
df.4 = cbind(df.1, df.3)
이 코드는 df.2와 순서를 유지하고 df.1에서 일치하는 데이터 만 추가합니다.
하나의 변수 만 추가 cbind()
해야하는 경우에는 필요하지 않습니다.
row.names(df.1) = df.1$key
df.2$data = df.1[df.2$key, "data"]
기지에 더 효율적인 방법이있을 수 있습니다. 이것은 함수로 만들기가 매우 간단합니다.
varorder <- names(mydata) # --- Merge
mydata <- merge(mydata, otherData, by="commonVar")
restOfvars <- names(mydata[!(names(mydata) %in% varorder)])
mydata[c(varorder,restOfvars)]
'IT이야기' 카테고리의 다른 글
Ubuntu 13.04의 R 3.0에 rJava를 설치할 수 없을 때 (0) | 2021.03.22 |
---|---|
leaflet의 마커, 클릭 이벤트 (0) | 2021.03.22 |
Java 8 람다 재귀 함수 (0) | 2021.03.21 |
파이썬 키 누름 감지 방법 (0) | 2021.03.21 |
commonjs / amd 모듈을 가져 오기위한 새로운 es6 구문, 즉 import foo = require ( 'foo') (0) | 2021.03.21 |