Mam listę wielu ramek data.frame, które chcę scalić. Problem polega na tym, że każda ramka data.frame różni się pod względem liczby wierszy i kolumn, ale wszystkie mają wspólne zmienne kluczowe (które wywołałem "var1"
i "var2"
w poniższym kodzie). Gdyby data.frames były identyczne pod względem kolumn, mógłbym tylko rbind
, dla których rbind.fill plyr wykonałby zadanie, ale nie jest tak w przypadku tych danych.
Ponieważ merge
polecenie działa tylko na 2 ramkach danych., Szukałem pomysłów w Internecie. Dostałem ten stąd , który działał doskonale w wersji R 2.7.2, a miałem to wtedy:
merge.rec <- function(.list, ...){
if(length(.list)==1) return(.list[[1]])
Recall(c(list(merge(.list[[1]], .list[[2]], ...)), .list[-(1:2)]), ...)
}
Nazwałbym tę funkcję tak:
df <- merge.rec(my.list, by.x = c("var1", "var2"),
by.y = c("var1", "var2"), all = T, suffixes=c("", ""))
Ale w dowolnej wersji R po wersji 2.7.2, w tym 2.11 i 2.12, ten kod kończy się niepowodzeniem z następującym błędem:
Error in match.names(clabs, names(xi)) :
names do not match previous names
(Nawiasem mówiąc, widzę inne odniesienia do tego błędu gdzie indziej bez rozdzielczości).
Czy jest jakiś sposób na rozwiązanie tego?
map_dfr()
lubmap_dfc()
dfs = [df1, df2, df3]
potemreduce(pandas.merge, dfs)
.Zmniejszenie sprawia, że jest to dość łatwe:
Oto w pełni przykład z wykorzystaniem niektórych próbnych danych:
A oto przykład wykorzystania tych danych do replikacji
my.list
:Uwaga: wygląda na to, że jest to prawdopodobnie błąd
merge
. Problem polega na tym, że nie ma możliwości sprawdzenia, czy dodanie sufiksów (w celu obsługi nakładających się niepasujących nazw) faktycznie czyni je unikalnymi. W pewnym momencie używa,[.data.frame
które robimake.unique
nazwy, powodującrbind
awarię.Najprostszym sposobem na naprawę jest pozostawienie zmiany nazwy pola dla duplikatów pól (których jest tutaj wiele) aż do
merge
. Na przykład:merge
/Reduce
Będzie wtedy działać.źródło
empty <- data.frame(x=numeric(0),a=numeric(0); L3 <- c(empty,empty,list.of.data.frames,empty,empty,empty)
zdarzyło się coś dziwnego, czego jeszcze nie odkryłem.Można to zrobić przy użyciu
merge_all
wreshape
opakowaniu. Możesz przekazać parametrymerge
za pomocą...
argumentuOto doskonały zasób na temat różnych metod scalania ramek danych .
źródło
Aby to zrobić, możesz użyć rekurencji. Nie zweryfikowałem następujących elementów, ale powinien dać ci właściwy pomysł:
źródło
Wykorzystam ponownie przykład danych z @PaulRougieux
Oto krótkie i słodkie rozwiązanie przy użyciu
purrr
itidyr
źródło
Funkcja
eat
mojego pakietu safejoin ma taką funkcję, jeśli podasz mu listę data.frames jako drugie wejście, to połączy je rekurencyjnie z pierwszym wejściem.Pożyczanie i rozszerzanie danych akceptowanej odpowiedzi:
Nie musimy brać wszystkich kolumn, możemy użyć pomocników select z tidyselect i wybrać (kiedy zaczynamy od
.x
wszystkich.x
kolumn są zachowane):lub usuń określone:
Jeśli lista ma nazwę, nazwy będą używane jako przedrostki:
Jeśli występują konflikty kolumn,
.conflict
argument pozwala rozwiązać problem, na przykład biorąc pierwszą / drugą, dodając je, łącząc je lub zagnieżdżając.trzymaj pierwszy:
zachowaj ostatnią:
Dodaj:
łączyć:
gniazdo:
NA
wartości można zastąpić za pomocą.fill
argumentu.Domyślnie jest to udoskonalona
left_join
ale dplyr sprzężeń są obsługiwane przez.mode
argumentu, rozmyte sprzężeń są również obsługiwane przezmatch_fun
argumentu (jest owinięty wokół pakietufuzzyjoin
) lub dając wzór taki jak~ X("var1") > Y("var2") & X("var3") < Y("var4")
doby
argumentu.źródło
Miałem listę ramek danych bez wspólnej kolumny identyfikatora.
Brakowało mi danych na wielu systemach plików. Były wartości Null. Ramki danych zostały utworzone przy użyciu funkcji tabel. Reduce, Scalanie, rbind, rbind.fill i im podobne nie mogły mi pomóc w osiągnięciu celu. Moim celem było stworzenie zrozumiałej scalonej ramki danych, bez znaczenia dla brakujących danych i wspólnej kolumny identyfikatora.
Dlatego wykonałem następującą funkcję. Może ta funkcja może komuś pomóc.
podąża za funkcją
Uruchamianie przykładu
źródło
Jeśli masz listę plików dfs, a kolumna zawiera „identyfikator”, ale na niektórych listach brakuje niektórych identyfikatorów, możesz użyć tej wersji funkcji Reduce / Merge, aby dołączyć wiele plików Df brakujących identyfikatorów wierszy lub etykiet:
źródło
Oto ogólne opakowanie, którego można użyć do konwersji funkcji binarnej na funkcję wielu parametrów. Zaletą tego rozwiązania jest to, że jest ono bardzo ogólne i może być stosowane do dowolnych funkcji binarnych. Musisz to zrobić tylko raz, a następnie możesz zastosować go w dowolnym miejscu.
Aby zilustrować ten pomysł, używam prostej rekurencji do wdrożenia. Można go oczywiście wdrożyć w bardziej elegancki sposób, który korzysta z dobrego wsparcia R dla funkcjonalnego paradygmatu.
Następnie możesz po prostu zawinąć w nią dowolne funkcje binarne i wywołać z parametrami pozycyjnymi (zwykle data.frames) w pierwszych nawiasach i nazwanymi parametrami w drugich nawiasach (takich jak
by =
lubsuffix =
). Jeśli nie ma nazwanych parametrów, pozostaw puste nawiasy.źródło