2013-10-02 2 views
8

suffixes (merge)은 공통 열 이름에서만 작동합니다. 병합하기 전에 수동으로 열을 업데이트하지 않고도 나머지 열까지 확장 할 수 있습니까?병합에서 접미사를 모두 비 포함 열로 확장

입니다

-

df1 <- data.table(
a = c(1,2,3,4,5,6), 
b = c('a','b','f','e','r','h'), 
d = c('q','l','o','n','q','z') 
) 

df2 <- data.table(
a = c(1,2,3,4,5,6), 
d = c('q','l','o','n','q','z') 
) 

colnames(merge(df1,df2, by = 'a', suffixes = c("1","2"))) 
#[1] "a" "b" "d1" "d2" what it does 
#[1] "a" "b1" "d1" "d2" what I'd like it to do 

나는이 mrip의 대답 @ 유사 취급하고있어 현재의 방법.

df1 <- data.table(
a = c(1,2,3,4,5,6), 
b = c('a','b','f','e','r','h'), 
r = c('a','b','f','e','r','h'), 
d = c('q','l','o','n','q','z') 
) 

df2 <- data.table(
a = c(1,2,3,4,5,6), 
c = c('a','b','f','e','r','h'), 
q = c('a','b','f','e','r','h'), 
d = c('q','l','o','n','q','z') 
) 

dfmerge <- (merge(df1,df2, by = c("a"), suffixes = c("1","2"))) 

setnames(
dfmerge, 
setdiff(names(df1),names(df2)), 
paste0(setdiff(names(df1),names(df2)),"1") 
) 

setnames(
dfmerge, 
setdiff(names(df2),names(df1)), 
paste0(setdiff(names(df2),names(df1)),"2") 
) 

colnames(dfmerge) 
#[1] "a" "b1" "r1" "d1" "c2" "q2" "d2" 
+0

아마도'a'가 아니라 마지막 예제에서'a1'을 의미할까요? – joran

+0

불편하지만'setnames'의 효율성으로 병합하기 전에 이름을 바꾸면 가장 간단한 해결책이 될지 궁금합니다. – A5C1D2H2I1M1N2O1R2T1

+0

@ joran, 나는 그들이 "by"칼럼이므로 그들이하지 않았다고 생각합니다. – A5C1D2H2I1M1N2O1R2T1

답변

10

간단한 해결책에 동일하게 작동합니다

mrg<-(merge(df1,df2, by = 'a', suffixes = c("1","2"))) 
setnames(mrg,paste0(names(mrg),ifelse(names(mrg) %in% setdiff(names(df1),names(df2)),"1",""))) 
setnames(mrg,paste0(names(mrg),ifelse(names(mrg) %in% setdiff(names(df2),names(df1)),"2",""))) 

> names(mrg) 
[1] "a" "b1" "d1" "d2" 

편집 : 상당히이 청소 나을 가르치는 리카르도 Saporta에 의한 의견에 감사 몇 가지 새로운 팁!

+0

+1 매우 좋습니다! 나는 이것을 많이 좋아한다 –

+0

@ 리카르도아 포르타 예! 고마워, 나는 혼란 스러웠다. 청소 했어. – mrip

+0

@RicardoSaporta 다시 한 번!고마워, 장래에''sep = "")를 많이 절약 할 수있을 것이다. 큰 팁 ~ – mrip

1

이 흥미로운 질문이고, 나는 매트 Dowle와 (주)는 merge.data.table에서 구현하는 가치가 무엇인가 생각하지 않는 merge을 연장하는 간단한 솔루션이 될 것이라고 의심한다.

DTs <- c("df1", "df2") 
suffixes <- seq_along(DTs) 

for (i in seq_along(DTs)) { 
    Name <- setdiff(colnames(get(DTs[i])), "a") 
    setnames(get(DTs[i]), Name, paste(Name, suffixes[i], sep = ".")) 
} 

merge(df1, df2, by = "a") # Will obviously work as you expect now 
+0

(나는 여기에 행해진 것처럼'get'을 사용하여 성능에 영향이 있는지 생각하기에는 너무 지쳤습니다.) – A5C1D2H2I1M1N2O1R2T1

4

은 다음을 시도해보십시오 : 원래 data.frames 무사 것을

colnames(
    mergeWithSuffix(df1,df2, by = 'a', suffixes = c("1","2")) 
) 
[1] "a" "b.1" "d.1" "d.2" 

공지 사항

여기에 마음에 온 하나의 방법입니다. 참조

require(data.table) 

mergeWithSuffix <- function(x, y, by, suffixes=NULL, ...) { 

    # Add Suffixes 
    mkSuffix(x, suffixes[[1]], merge.col=by) 
    mkSuffix(y, suffixes[[2]], merge.col=by) 

    # Merge 
    ret <- merge(x, y, by = by, suffixes = NULL, ...) 

    # Remove Suffixes 
    undoSuffix(x, suffixes[[1]], merge.col=by) 
    undoSuffix(y, suffixes[[2]], merge.col=by) 
    return(ret) 
} 

mkSuffix <- function(x, sfx, sep=".", merge.col=NULL) { 
    nms <- setdiff(names(x), merge.col) 
    setnames(x, nms, paste(nms, sfx, sep=".")) 
} 

undoSuffix <- function(x, sfx, sep=".", merge.col=NULL) { 
    nms <- setdiff(names(x), merge.col) 
    setnames(x, nms, sub(paste0(get("sep"), sfx, "$"), "", nms)) 
} 

공지 setnames 그 다음 작동하므로 오버 헤드가 거의 무시할로

colnames(df1) 
[1] "a" "b" "d" 

colnames(df2) 
[1] "a" "d" 

함수이다. 다른 곳에서 논의 된 바와 같이 또한,이 data.frames 및 data.table

+0

이 답변은 여러 데이터 프레임을 병합하도록 일반화 될 수 있습니다 : https : // stackoverflow. com/questions/8091303/동시 병합 - 다중 데이터 프레임 인리스트 – user3226167