2013-10-02 17 views
8

suffixes w merge działa tylko na wspólnych nazwach kolumn. Czy mimo to można rozszerzyć to również na pozostałe kolumny bez ręcznego aktualizowania kolumn przed scaleniem?Przedłużanie przyrostków w połączeniu z wszystkimi kolumnami innymi niż z podziałem

To jest -

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 

Obecny sposób mam operowania tym przypomina @ odpowiedź mrip użytkownika.

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

Przypuszczalnie masz na myśli "a1" w tym ostatnim przykładzie, a nie tylko "a"? – joran

+0

Jest to niewygodne, ale z wydajnością "setnames", zastanawiam się, czy zmiana nazwy przed scaleniem stanie się najbardziej prostym rozwiązaniem. – A5C1D2H2I1M1N2O1R2T1

+0

@joran, zgaduję, że nie, ponieważ jest to kolumna "od". – A5C1D2H2I1M1N2O1R2T1

Odpowiedz

10

proste rozwiązanie:

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" 

Edit: dzięki komentarzach Ricardo Saporta do czyszczenia to się znacznie i uczy mnie kilka nowych wskazówek!

+0

+1 Bardzo ładnie! Bardzo to lubię –

+0

@RicardoSaporta Tak! Dzięki, byłem zdezorientowany. Oczyścić to. – mrip

+0

@RicardoSaporta Tak, znowu!Dzięki, zaoszczędzi mi to dużo ', sep =" ")' w przyszłości. Wielka wskazówka ~ – mrip

1

To jest ciekawe pytanie, i wątpię, że rozszerzenie merge byłoby proste rozwiązanie chyba Matt Dowle and Co., że to jest coś warta realizacji w merge.data.table.

Oto jedno podejście, które przyszło na myśl:

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

(Jestem zbyt zmęczony, aby zastanowić się, czy są jakieś skutki wydajności używania 'get' tak, jak zostało to zrobione tutaj ...) – A5C1D2H2I1M1N2O1R2T1

4

Spróbuj wykonać następujące czynności:

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

Zauważ, że oryginalny data.frames są nienaruszone.

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

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

Funkcje są następujące

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

Zauważ, że setnames prace odniesienia, więc koszt jest znikomy. Ponadto, jak wspomniano w innym miejscu, to działa równie dobrze na data.frames i data.table

+0

Ta odpowiedź może zostać uogólniona w celu scalenia wielu ramek danych: https: // stackoverflow. com/questions/8091303/while-merge-multiple-data-frames-in-a-list – user3226167