2017-11-17 11 views
1

2つのテーブルを使用すると、特定の条件で正しいテーブルに参加することは可能ですか?Dplyrがケースに参加する場合

この場合、右テーブルProductHierarchyType == "LINE"の場合は、左側のテーブルの列名ProductLineIDに条件付きで参加したいと考えています。 これは、CLASS> GROUP> SUBGROUP> LINEの階層に基づいて引き続き行われます。

prodmap2を使用して追加の列を作成しようとしましたが、これにより、その条件を正しく取得する方法がわかりません。

prodmap2<-prodmap%>% mutate(ProdClass = case_when(ProductHierarchyType=="CLASS" ~ ProductHierarchyID))%>% mutate(ProdGroup = case_when(ProductHierarchyType=="GROUP" ~ ProductHierarchyID))%>% mutate(ProdSUBGroup = case_when(ProductHierarchyType=="SUBGROUP" ~ ProductHierarchyID))%>% mutate(ProdLine = case_when(ProductHierarchyType=="LINE" ~ ProductHierarchyID))

左表:

structure(list(TerritoryKey = c("800046", "800046", "800046", 
"800046", "800046", "800046"), Material = c("000-40", "003-01", 
"003-40", "004-00", "004-05", "005-40"), TotalSales = c(61.68, 
94.27, 48227.14, 422.88, 45.4, 3723.92), ProductClassID = c("0012", 
"0012", "0012", "0012", "0012", "0012"), ProductGroupID = c("00120001", 
"00120001", "00120001", "00120002", "00120002", "00120001"), 
    ProductSubGroupID = c("001200010002", "001200010002", "001200010002", 
    "001200020002", "001200020002", "001200010002"), ProductLineID = c("001200010002000001", 
    "001200010002000001", "001200010002000001", "001200020002000001", 
    "001200020002000001", "001200010002000001"), StartDate = c("1/1/2016", 
    "1/1/2016", "1/1/2016", "1/1/2016", "1/1/2016", "1/1/2016" 
    ), EndDate = c("12/31/2099", "12/31/2099", "12/31/2099", 
    "12/31/2099", "12/31/2099", "12/31/2099")), .Names = c("TerritoryKey", 
"Material", "TotalSales", "ProductClassID", "ProductGroupID", 
"ProductSubGroupID", "ProductLineID", "StartDate", "EndDate"), row.names = c(NA, 
-6L), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), vars = "TerritoryKey", drop = TRUE, indices = list(
    0:5), group_sizes = 6L, biggest_group_size = 6L, labels = structure(list(
    TerritoryKey = "800046"), row.names = c(NA, -1L), class = "data.frame", vars = "TerritoryKey", drop = TRUE, .Names = "TerritoryKey")) 

右表:

structure(list(CompProfileID = c("ALTC", "ALTC", "ALTC", "ALTC", 
"ALTC", "ALTC"), ProductBucketID = c("CORE", "CORE", "CORE", 
"CORE", "CORE", "CORE"), ProductHierarchyID = c("001200010001000001", 
"001200010001000003", "001200010001000009", "001200010002", "001200010003000001", 
"001200010004000004"), ProductHierarchyType = c("LINE", "LINE", 
"LINE", "SUBGROUP", "LINE", "LINE"), ExclusionFlag = c("N", "N", 
"N", "N", "N", "N"), StartDate = c("2017-01-01", "2017-01-01", 
"2017-01-01", "2017-01-01", "2017-01-01", "2017-01-01"), EndDate = c("2099-12-31", 
"2099-12-31", "2099-12-31", "2099-12-31", "2099-12-31", "2099-12-31" 
), ExclusionType = c("", "", "", "", "", "")), .Names = c("CompProfileID", 
"ProductBucketID", "ProductHierarchyID", "ProductHierarchyType", 
"ExclusionFlag", "StartDate", "EndDate", "ExclusionType"), row.names = c(NA, 
6L), class = "data.frame") 

答えて

2

条件付きで複数の列に参加することは困難です。参加する前にデータを"tidy data"形式に変換することをお勧めします。つまり、IDに関連する列をキーと値の1組の列にまとめます。

library(tidyr) 
library(dplyr, warn.conflicts = FALSE) 

left_table_tidy <- left_table %>% 
    ungroup() %>% 
    tibble::rowid_to_column(var = "unique_ID") %>% 
    gather(key = "ID_type", value = "ID", matches("Product.*ID")) %>% 
    mutate(ID_type = recode(ID_type, 
          ProductClassID = "CLASS", 
          ProductGroupID = "GROUP", 
          ProductSubGroupID = "SUBGROUP", 
          ProductLineID = "LINE")) 

その後、あなたはIDとIDの種類によってデータを結合することができます。

table_joined <- inner_join(left_table_tidy, 
          right_table, 
          by = c("ID_type" = "ProductHierarchyType", 
            "ID"  = "ProductHierarchyID")) 

このように、この結合は、元の行ごとに複数のタイプにヒットする可能性があります。したがって、 "CLASS> GROUP> SUBGROUP> LINE"の順番で行をソートし、重複を除去するために最初の行を選択する必要があります。

table_joined %>% 
    group_by(unique_ID) %>% 
    arrange(factor(ID_type, levels = c("CLASS", "GROUP", "SUBGROUP", "LINE"))) %>% 
    slice(1L) 
#> # A tibble: 4 x 14 
#> # Groups: unique_ID [4] 
#> unique_ID TerritoryKey Material TotalSales StartDate.x EndDate.x 
#>  <int>  <chr> <chr>  <dbl>  <chr>  <chr> 
#> 1   1  800046 000-40  61.68 1/1/2016 12/31/2099 
#> 2   2  800046 003-01  94.27 1/1/2016 12/31/2099 
#> 3   3  800046 003-40 48227.14 1/1/2016 12/31/2099 
#> 4   6  800046 005-40 3723.92 1/1/2016 12/31/2099 
#> # ... with 8 more variables: ID_type <chr>, ID <chr>, CompProfileID <chr>, 
#> # ProductBucketID <chr>, ExclusionFlag <chr>, StartDate.y <chr>, 
#> # EndDate.y <chr>, ExclusionType <chr> 
+0

私はこれがうまくいくと思いますが、仕事で月曜日に確認します。大きなセットに重複がある可能性があることはわかっていますが、それを個別にテストします。前に 'slice(1L)'を見たことがありますが、どういう仕組みか分かりません。それは各リストの最初のものですか? – GregdeLima

+1

'slice()'は '[、]'のような位置で行を選択します。一つの大きな違いは、 'slice()'はグループ単位であることです。グループ化されたdata.frameを渡すと、各グループから指定された行の位置を取得します。 'slice(1L)'は 'filter(row_number()== 1L)'に相当します。 – yutannihilation

関連する問題