2017-01-30 7 views
1

最初のチェーンと結合された2つの他のデータフレームの値に基づいてデータフレームを更新する必要があります。私は米国のレコードの郡でadministrative_area_level_2にNA値を更新する必要がチェーン結合による複雑な条件

 administrative_area_level_1 administrative_area_level_2  country  locality 
    1      Arizona    Maricopa County United States  Phoenix 
    2  District of Columbia      <NA> United States Washington 
    3      <NA>      <NA>   India   <NA> 
    4     New York    Albany County United States  Albany 
    5      Utrecht     Nieuwegein Netherlands Nieuwegein 
    6     Connecticut   Fairfield County United States  Stamford 
    707     Illinois      <NA> United States   <NA> 
    4241     Illinois      <NA> United States West Chicago 
999998      Alabama      <NA> United States  Altoona 
999999    Pennsylvania      <NA> United States Washington 

t_offices DF

ターゲットは、ここで関心の4つのフィールドがあります。値はDF t_placesにあります。

 state_ab   place_name     county_name place_nameshort 
    1  AL   Abanda CDP    Chambers County   Abanda 
    2  AL  Abbeville city     Henry County  Abbeville 
    3  AL  Adamsville city    Jefferson County  Adamsville 
    4  AL   Addison town    Winston County   Addison 
    5  AL   Akron town     Hale County   Akron 
    6  AL  Alabaster city    Shelby County  Alabaster 
    12  AL   Altoona town Blount County, Etowah County   Altoona 
    4298  DC  Washington city   District of Columbia  Washington 
    7527  IL West Chicago city    DuPage County  Washington 
32611  PA Washington township    Armstrong County West Chicago 
32612  PA Washington township     Berks County  Washington 

place_nameshortは指定せずにplace_nameの短縮バージョン(例えば「都市」、「町」など)である

私は中の状態や場所にt_officest_placesに参加します正しい郡を得るために注文する。これは、county_nameにカンマで区切られた複数の郡が含まれている可能性があり、2)切り捨てられたplace_nameshortが同じ状態で同義語を返す可能性があるため、1)複数の郡を返す可能性があります。私は郡が曖昧である場合にのみ(郡が返されます)が必要です。

t_placesだけstate_abが含まれているので、私は、第三のデータフレームstate_nameためr_states必要があります。state_abr_statest_placesに参加することで

state_ab    state_name 
1  AL    Alabama 
2  AK     Alaska 
3  AZ    Arizona 
4  AR    Arkansas 
5  CA    California 
6  CO    Colorado 
9  DC District of Columbia 
17  IL    Illinois 
42  PA   Pennsylvania 

を、私はt_offices$administrative_area_level_1state_nameマッチ得ることができます。

これは、州内の同義語のために複数の郡を管理するものではなく、とにかく動作しないため、不完全です。

no_county <- (!is.na(t_offices$country) 
      & t_offices$country == "United States" 
      & !is.na(t_offices$administrative_area_level_1) 
      & is.na(t_offices$administrative_area_level_2) 
      & !is.na(t_offices$locality)) 

t_offices$administrative_area_level_2[no_county] <- 
    t_places$county_name[!grepl(",", t_places$county_name) 
         & match(t_places$place_nameshort, t_offices$locality[no_county]) 
         & match(t_places$state_ab, 
           r_states$state_ab[match(r_states$state_name, 
                 t_offices$administrative_area_level_1[no_county])])] 

EDIT:r2evans'アドバイス@以下は、ここではまだ動作しません。私の新しいコーディング試み、です:ここで

# split multiple counties into columns 
library(splitstackshape) 
t_places <- cSplit(t_places, "county_name", sep = ", ", drop = F, type.convert = F) 

# merge state names into places 
places_statename <- merge(t_places, r_states[,2:3]) 

# define condition to select t_offices records in U.S. with state and place but no county 
no_county <- (
    # country is U.S. 
    !is.na(t_offices$country) 
    & t_offices$country == "United States" 
    # with state 
    & !is.na(t_offices$administrative_area_level_1) 
    # blank county 
    & is.na(t_offices$administrative_area_level_2) 
    # with place 
    & !is.na(t_offices$locality)) 

# update blank counties 
t_offices$administrative_area_level_2[no_county] <- 
    # unambiguous counties 
    places_statename$county_name_1[is.na(places_statename$county_name_2) 
           # locality matches place 
           & match(t_offices$locality[no_county], places_statename$place_nameshort) 
           # administrative_area_level_1 matches state 
           & match(t_offices$administrative_area_level_1[no_county],places_statename$state_name)] 
+1

「merge」または「dplyr :: left_join」と友人を介して直接結合をサポートするために、データを改革することをお勧めします。これにより、すべての作業が大幅に簡単になり、より堅牢になり、作業のトラブルシューティングが容易になります。開始: 'county_name'にカンマ区切りの複数の値を入れることができる場合は、' tidyr :: separate'のように分割してから 'tidyr :: gather'を使います(これにより、より直感的に/簡単に結合できます。質問は再現性があり、そのままではすべての要件を満たす代表的なデータはありません。 – r2evans

+0

@ r2evansご意見ありがとうございます!質問を再現できるように(実際のメークアップの)サンプルデータを追加しました。 – syre

+0

@ r2evansは溶けませんが、複数の列に転記してください – syre

答えて

0

は私の長いソリューションです。おそらく、より短く、よりエレガントなものがあります。

# split multiple counties into columns 
library(splitstackshape) 
t_places <- cSplit(t_places, "county_name", sep = ", ", drop = F, type.convert = F) 
# subset original places with single county 
places_singlecounty <- t_places[is.na(places_statename$county_name_2), c(1,8,9)] 
# subset truncated places with single county 
library(data.table) 
setDT(places_singlecounty) 
places_singlecounty <- merge(places_singlecounty, 
          places_singlecounty[, .N, by = c("state_ab", "place_nameshort")][N == 1, 1:2]) 
# merge state names into single-county truncated places 
places_statename <- merge(places_singlecounty, r_states[,2:3], by = "state_ab") 

# define condition to select t_offices records in U.S. with state and place but no county 
no_county <- (
    # country is U.S. 
    !is.na(t_offices$country) 
    & t_offices$country == "United States" 
    # with state 
    & !is.na(t_offices$administrative_area_level_1) 
    # NA county 
    & is.na(t_offices$administrative_area_level_2) 
    # with place 
    & !is.na(t_offices$locality)) 

# update t_offices NA counties based on single-county truncated places 
setDT(t_offices) 
t_offices[no_county, administrative_area_level_2 := 
      places_statename[.(.SD), county_name_1, 
          on = c(state_name = "administrative_area_level_1", 
            place_nameshort = "locality")]]