2010-09-06 13 views
31

Mam (znowu) problem z łączeniem ramek danych w R. Ale tym razem jedna z nich to SpatialPolygonDataFrame (SPDF), a druga to zwykle data.frame (DF). SPDF ma około 1000 rzędach DF tylko 400. Oba mają wspólną kolumnę QDGCJak dołączyć proste dane.frame do SpatialPolygonDataFrame w R?

Teraz próbowałem

oo <- merge(SPDF,DF, by="QDGC", all=T) 

ale to tylko wyniki w normalnym data.frame, a nie ramka danych wielokąt przestrzenny nie więcej. Czytam gdzieś indziej, że to nie działa, ale nie rozumiem, co robić w takim przypadku (musi coś zrobić z kolumnami ID, użyj kombinacji)

oooh takie trudne pytanie, podaję. ..

Dzięki! Jens

Odpowiedz

40

Niech df = ramka danych, sp = przestrzenny obiekt wielokąta i przez = nazwa lub numer kolumny wspólnej kolumny. Następnie można scalić ramkę danych w obiekt sp, stosując następujący wiersz kodu:

[email protected] = data.frame([email protected], df[match([email protected][,by], df[,by]),]) 

Oto jak działa kod. Funkcja dopasowywania wewnątrz wyrównuje kolumny, aby zachować porządek. Więc kiedy połączymy go z danymi sp @, porządek zostanie poprawnie zachowany. Szybkim sprawdzeniem, czy kod zadziałał, jest sprawdzenie dwóch kolumn odpowiadających wspólnej kolumnie i sprawdzenie, czy są one identyczne (wspólne kolumny zostają zduplikowane i łatwo jest usunąć kopię, ale zachowuję ją tak, jak jest dobra kontrola)

+1

Dziękuję bardzo za dużo! Uratowałeś mój wieczór! I prawdopodobnie także przez cały tydzień! Wszystko działało doskonale. – Jens

+0

@Ramnath Czy to rozwiązanie będzie działać, jeśli ramka danych przestrzennych ma więcej wierszy (wielokątów) niż dane scalone? A także w przeciwnym przypadku - kiedy w połączonych danych jest więcej obserwacji? – radek

+0

Jak by to było inaczej, gdyby oba obiekty były 'SpatialP * DataFrame's? – gregmacfarlane

6

Funkcja scalania może utworzyć ramkę danych o większej liczbie wierszy niż oryginały, jeśli nie ma prostego odwzorowania 1-1 dwóch ramek danych. W takim przypadku musiałaby skopiować całą geometrię i utworzyć wiele wielokątów, co prawdopodobnie nie jest dobre.

Jeśli masz ramkę danych o tej samej liczbie rzędów co SpatialPointsDataFrame, możesz po prostu bezpośrednio zastąpić @ data.

library(sp) 
example(overlay) # to get the srdf object 
[email protected] 
spplot(srdf) 
[email protected]=data.frame(x=runif(3),xx=rep(0,3)) 
spplot(srdf) 

jeśli uzyska liczbę wierszy źle:

[email protected]=data.frame(x=runif(2),xx=rep(0,2)) 
spplot(srdf) 
Error in data.frame(..., check.names = FALSE) : 
    arguments imply differing number of rows: 3, 2 
+0

Dobrze zrobiłem follwing: (1) oo <- scalanie (SPDF, DF, przez = "QDGC" , all = T) (2) SPDF @ data <- oo (3) działka (SPDF) dane są teraz dostępne, ale w bardzo złej kolejności. może powinienem coś posortować? – Jens

+0

ouch. powinienem to sprawdzić. – Spacedman

2

Może funkcja joinCountryData2Map w pakiecie rworldmap może dać inspirację. (Ale mogę się mylić, tak jak ostatnio).

16

to jest tak łatwe, jak to:

require(sp) # the trick is that this package must be loaded! 

oo <- merge(SPDF,DF, by="QDGC") 

Przetestowałem przez siebie. Ale działa tylko wtedy, gdy używasz merge from package sp. Jest to ustawienie domyślne, gdy ładowany jest pakiet sp. merge funkcja jest następnie przeciążana i używana jest sp::merge, jeśli pierwszym argumentem jest struktura przestrzenna.

+1

To działało naprawdę dobrze dla mnie! Uważam jednak, że warto zauważyć, że niektóre problemy mogą się pojawić, jeśli ramka danych i SPDF nie mają tej samej liczby wierszy. Wystąpił błąd ("liczba niezgodności obiektów") powstały w wyniku tego problemu. Wreszcie, udało mi się przeprowadzić scalenie, dodając "all.x = TRUE" (gdzie x to SPDF). –

0

Jeszcze jednym rozwiązaniem jest użycie funkcji append_data z pakietu tmaptools. Nazywa się z tymi argumentami:

append_data(shp, data, key.shp = NULL, key.data = NULL, 
    ignore.duplicates = FALSE, ignore.na = FALSE, 
    fixed.order = is.null(key.data) && is.null(key.shp)) 

To trochę niefortunne, że to się nazywa append odkąd Rozumiem dołączyć więcej ina poczucie rbind i chcemy mieć coś podobnego join lub merge tutaj.

Zignorowanie tego faktu, funkcja jest naprawdę przydatna w upewnianiu się, że twoje sprzężenia są poprawne i jeśli niektóre wiersze są obecne tylko po jednej stronie łączenia. Od docs:

Pod pokrycia (pozycje kształt nie odpowiadają rekordy danych), ponad pokrycia (rekordy danych, które nie odpowiadają na kształt przedmiotów odpowiednio), jak również istnienie zduplikowanych wartości klucza są automatycznie sprawdzane i zgłaszane za pośrednictwem komunikatów konsoli. Z under_coverage i over_coverage pod i nad pokrycia kluczowych wartości z ostatniego append_data wezwanie może zostać odzyskane,