2015-03-05 9 views
6

Widziałem podobny post na ten temat, ale nie mogłem zrozumieć rozwiązania. Zasadniczo mam tabelę danych (DT1) z wynikami i niektórymi NA. Wszędzie tam, gdzie istnieje "NA", chciałbym proces, który odwołuje się do innej tabeli danych (DT2), która ma wspólną kolumnę w obu tabelach (trakt), a następnie aktualizuje NA w DT1 wartością kolumny wyników DT2. Wybieram klasę tabeli danych, ponieważ uważam, że jest to skuteczna opcja.Zaktualizuj kolumnę NA w jednej tabeli danych z wartością z kolumny w innej tabeli danych

DT1

  tract CreditScore  
1: 36107020401   635 
2: 36083052403   NA 
3: 36091062602   NA 
4: 36067013000   NA 
5: 36083052304   NA 

DT2

  tract CreditScore 
1: 36107020401   635 
2: 36083052403   650 
3: 36091062602   335 
4: 36067013000   777 
5: 36083052304   663 
+0

Jeśli używasz pakietu 'data.table', musisz to wyjaśnić w pytaniu. Nie jest dla mnie jasne, czy masz na myśli strukturę danych charakterystyczną dla 'data.table' czy też struktury bazowej' data.frame'. Czy istnieje powód (np. Obawy dotyczące rozmiaru/pamięci), że nie można po prostu scalić dwóch tabel i użyć 'ifelse()' do utworzenia nowej kolumny, która ma odpowiednią wartość? –

+1

@Alex, tak, jest. Równie dobrze mógłby załadować dane do Excela i zrobić "widok", nieprawdaż? Mówiąc dokładniej, 'data.table' może dokonać * binarnego * łączenia i aktualizacji kolumn * przez odniesienie podczas dołączania *. Byłoby to bardziej wydajne niż 'scalanie' +' ifelse' przez kilka czynników na dużym zbiorze danych. –

+0

Dziękuję za uwagi. Tak, głównym powodem, dla którego zdecydowałem się użyć pakietu data.table jest jego ogólna wydajność. Nie chciałem dodawać kolejnej kolumny do DT1, jeśli nie potrzebowałem. Spróbuję odpowiedzi poniżej i zobaczę, jak to działa ..... dzięki i pozdrawiam! – user3067851

Odpowiedz

9

Utworzyliśmy nowy (i bardziej kompleksowy) HTML vignettes dla niektórych data.table pojęć. Zajrzyj here dla innych winiet, nad którymi pracujemy. Pracuję nad winietami dla złączeń, które, gdy to zrobię, zapewnią lepsze wyjaśnienie tego typu problemów.


Chodzi o to, aby pierwszy setkey() na DT1 na kolumnie tract.

setkey(DT1, tract) 

W data.tables, sprzężenie formy x[i] wymaga klucza dla x, ale niekoniecznie dla i. Wynika to z dwóch scenariuszy:

  • Jeśli i posiada również zestaw kluczy - pierwszy klucz kolumna i jest porównywana z pierwszego klucza kolumnie x, drugi z drugiej i tak dalej ..

  • Jeśli i nie posiada zestawu kluczy - pierwsza kolumna i jest porównywana z pierwszej klucz kolumnie x, drugiej kolumnie i przeciwko drugim klucz kolumnie x i tak dalej ..

W tym przypadku, ponieważ Twoja pierwsza kolumna w i jest również tract będziemy pomijać ustawienie klucza na i.

Następnie wykonujemy sprzężenie w postaci x[i]. Robiąc to, dla każdego i obliczane są pasujące indeksy wierszy w x, a następnie wynik sprzężenia zostaje zmaterializowany. Jednak nie chcemy, aby cały wynik sprzężenia był nowym plikiem data.table. Przeciwnie, chcemy zaktualizować DT1 's CreditScore kolumnę DT2 temat tych pasujących wierszy ..

W data.tables, możemy wykonać tę operację łączenia, dostarczając wyraz w j, w następujący sposób:

DT1[DT2, CreditScore := i.CreditScore] 
#   tract CreditScore 
# 1: 36067013000   777 
# 2: 36083052304   663 
# 3: 36083052403   650 
# 4: 36091062602   335 
# 5: 36107020401   635 

DT1[DT2 część znajduje pasujące wiersze w DT1 dla każdego wiersza w DT2. A jeśli jest dopasowanie, chcemy zaktualizować wartość DT2 w DT1.Osiągamy to, używając parametru i.CreditScore - odnosi się on do kolumny DT2() (prefiks używany do odróżniania kolumn o identycznych nazwach między x i i data.tables).


Aktualizacja: Jak zauważył pod uwag, powyższe rozwiązanie byłoby również zaktualizować wartości non-NA w DT1. Dlatego droga do zrobienia byłoby:

DT1[is.na(CreditScore), CreditScore := DT2[.(.SD), CreditScore]] 

Z powyższych wierszy gdzie CreditScore z DT1 jest NA wymienić CreditScore z DT1 z wartościami z CreditScore uzyskanych od łączenia z DT2[.(.SD)], gdzie .SD odpowiada podzbioru danych .table, który zawiera wszystkie wiersze, gdzie CreditScore jest NA.

HTH

+0

Czy mam rację, że korzysta z 'CreditScore' z' DT2' dla każdego pasującego 'tract'? Jak rozumiem OP, wartość 'DT2' powinna być wzięta tylko wtedy, gdy jest' NA' w 'DT1'. W podanym przykładzie nie ma to znaczenia, ponieważ w obu tabelach jest 635 dla wspólnego rekordu. Jeśli były inne, w jaki sposób można zachować wartość "DT1"? – DaveTurek

+0

@DaveTurek, jasne, dzięki. Zaktualizowano teraz. – Arun

+1

Powiedziano mi, że '.SD' jest zablokowany podczas próby wdrożenia tego rozwiązania. – MichaelChirico