2017-08-26 329 views
0

我有兩個MySQL表。其中一個包含犯罪案件的數據(即案件號碼,地點),另一個案件包含針對案件「案件」表格中每個案件提交的犯罪行爲(即違反哪些法律,條款,段落)。因此,我與每一起犯有多重罪行的案件都有1:n的關係。現在,我想加入這兩個表格,但不知道如何做到最好。更改data.frame結構

table "cases" 
ID/casenumber/... 
--------------------- 
1/2015-33323 
2/2016-33213 
3/2017-88873 


table "offences" 
ID/caseId/law/article/... 
--------------------- 
1/1  /law1/110 /... 
2/1  /law1/111 /... 
3/1  /law2/239 /... 
4/2  /law1/342 /... 
5/2  /law3/920 /... 
6/3  /law1/820 /... 

爲了加入兩個data.frames我應該得到的罪行表成這樣一種形式:

caseId/offence1law/offence1art/offence2law/offence2art/... 
--------------------- 
1 /law1  /110  /law1  /111/... 
2 /law1  /342  /law3  /920/... 
3 /law3  /820  /NA  /NA/... 

有誰知道如何做到這一點?我所尋找的表格中的變量數量取決於所犯罪行的數量。

非常感謝您的提示!

+1

您的結果不使用你的第一個表中的所有;這只是你的第二個更廣泛的形式。雖然你可以使用tidyr創建它,但我最好的建議是不要這樣做,因爲它是一個雜亂無章且數據結構不太好的數據結構,其變量隱藏在列名稱中。 – alistaire

+0

所以你想加入'caseId'? 'dplyr'已加入函數,請檢查'left_join'例如 – Dambo

+0

@ Dambo加入並不是問題。問題是,「右」表具有與「左」表不同的結構。 –

回答

1

以下是使用dplyrtidyr創建所需的進攻表信息的解決方案。 offences5是最終輸出。

想法是使用gather,unitespread來創建所需的寬格式表格。之後,使用left_join來合併數據。請注意,最後的selectsetNames正在選擇並重命名與OP所需輸出完全相同的列。但是,如果列順序不重要,則這些調用是可選的。

該解決方案與cases數據幀無關。但是,如果OP需要,如果offences5準備就緒,則很容易進行left_join

library(dplyr) 
library(tidyr) 

offences2 <- offences %>% 
    group_by(caseId) %>% 
    mutate(ID = 1:n(), Law = "law", Art = "art") %>% 
    unite(Law2, ID, Law, remove = FALSE, sep = "") %>% 
    unite(Art2, ID, Art, remove = TRUE, sep = "") 

offences3 <- offences2 %>% 
    select(caseId, law, Law2) %>% 
    spread(Law2, law) 

offences4 <- offences2 %>% 
    select(caseId, article, Art2) %>% 
    spread(Art2, article) 

offences5 <- offences3 %>% 
    left_join(offences4, by = "caseId") %>% 
    select(c("caseId", sapply(1:length(unique(offences$law)), 
          function(i) paste0(i, c("law", "art"))))) %>% 
    setNames(c("caseId", paste0("offence", colnames(.[, -1])))) 

offences5 
# A tibble: 3 x 7 
# Groups: caseId [3] 
    caseId offence1law offence1art offence2law offence2art offence3law offence3art 
    <int>  <chr>  <int>  <chr>  <int>  <chr>  <int> 
1  1  law1   110  law1   111  law2   239 
2  2  law1   342  law3   920  <NA>   NA 
3  3  law1   820  <NA>   NA  <NA>   NA 

數據:

offences <- read.table(text = "ID caseId law article 
         1 1 law1 110 
         2 1 law1 111 
         3 1 law2 239 
         4 2 law1 342 
         5 2 law3 920 
         6 3 law1 820", 
         header = TRUE, stringsAsFactors = FALSE)