2016-12-03 76 views
0

我有R中的數據集而我試圖通過列級和年份,看起來像這樣聚集:R:基於因子水平和兩年的有條件合計

City State Year Status  Year_repealed PolicyNo 
    Pitt PA  2001 InForce      6 
    Phil. PA  2001 Repealed  2004   9 
    Pitt PA  2002 InForce      7 
    Pitt PA  2005 InForce      2 

我想創造就是對於每一年,我會在考慮到政策被廢除的日期之後在各州彙總政策號。結果,那麼我會得到的是:

Year State PolicyNo 
    2001  PA  15 
    2002  PA  22 
    2003  PA  22 
    2004  PA  12 
    2005  PA  14 

我不知道如何去分割和彙總數據爲條件廢除數據,想知道是否有一種方法來實現這一點很容易爲R。

回答

2

它可以幫助你把這個問題分解成兩個不同的問題。

  1. 獲取一張表,顯示每個城市州年的PolicyNo變化。
  2. 總結該表以顯示每個州一年的政策號。

要完成(1)我們添加缺失的年份NA PolicyNo,並添加廢除作爲負面PolicyNo意見。

library(dplyr) 

df = structure(list(City = c("Pitt", "Phil.", "Pitt", "Pitt"), State = c("PA", "PA", "PA", "PA"), Year = c(2001L, 2001L, 2002L, 2005L), Status = c("InForce", "Repealed", "InForce", "InForce"), Year_repealed = c(NA, 2004L, NA, NA), PolicyNo = c(6L, 9L, 7L, 2L)), .Names = c("City", "State", "Year", "Status", "Year_repealed", "PolicyNo"), class = "data.frame", row.names = c(NA, -4L)) 

repeals = df %>% 
    filter(!is.na(Year_repealed)) %>% 
    mutate(Year = Year_repealed, PolicyNo = -1 * PolicyNo) 
repeals 
# City State Year Status Year_repealed PolicyNo 
# 1 Phil. PA 2004 Repealed   2004  -9 

all_years = expand.grid(City = unique(df$City), State = unique(df$State), 
         Year = 2001:2005) 

df = bind_rows(df, repeals, all_years) 
#  City State Year Status Year_repealed PolicyNo 
# 1 Pitt PA 2001 InForce   NA  6 
# 2 Phil. PA 2001 Repealed   2004  9 
# 3 Pitt PA 2002 InForce   NA  7 
# 4 Pitt PA 2005 InForce   NA  2 
# 5 Phil. PA 2004 Repealed   2004  -9 
# 6 Pitt PA 2001  <NA>   NA  NA 
# 7 Phil. PA 2001  <NA>   NA  NA 
# 8 Pitt PA 2002  <NA>   NA  NA 
# 9 Phil. PA 2002  <NA>   NA  NA 
# 10 Pitt PA 2003  <NA>   NA  NA 
# 11 Phil. PA 2003  <NA>   NA  NA 
# 12 Pitt PA 2004  <NA>   NA  NA 
# 13 Phil. PA 2004  <NA>   NA  NA 
# 14 Pitt PA 2005  <NA>   NA  NA 
# 15 Phil. PA 2005  <NA>   NA  NA 

現在的表格顯示了每個城市州一年並且包含廢止。這是我們可以總結的一張表格。

df = df %>% 
    group_by(Year, State) %>% 
    summarize(annual_change = sum(PolicyNo, na.rm = TRUE)) 
df 
# Source: local data frame [5 x 3] 
# Groups: Year [?] 
# 
# Year State annual_change 
# <int> <chr>   <dbl> 
# 1 2001 PA   15 
# 2 2002 PA    7 
# 3 2003 PA    0 
# 4 2004 PA   -9 
# 5 2005 PA    2 

這讓我們在每個州一年的PolicyNo變化。對這些變化的累計總和會使我們的水平。

df = df %>% 
    ungroup() %>% 
    mutate(PolicyNo = cumsum(annual_change)) 
df 
# # A tibble: 5 × 4 
# Year State annual_change PolicyNo 
# <int> <chr>   <dbl> <dbl> 
# 1 2001 PA   15  15 
# 2 2002 PA    7  22 
# 3 2003 PA    0  22 
# 4 2004 PA   -9  13 
# 5 2005 PA    2  15 
+0

非常感謝你@effel !!!它的工作完美。 –

+0

如果你不介意的話,還有一個問題@effel。如果我有多個政策編號欄,是否有辦法一次執行此分析? –

+0

是的,我建議融化更廣泛的表格並將group_by調用的變量列(指示策略)作爲一個標識符添加。如果以上工作正常,請隨時接受答案。 – effel

0

隨着data.table包如下,你可以這樣做:

melt(setDT(dat), 
    measure.vars = c(3,5), 
    value.name = 'Year', 
    value.factor = FALSE)[!is.na(Year) 
          ][variable == 'Year_repealed', PolicyNo := -1*PolicyNo 
          ][CJ(Year = min(Year):max(Year), State = State, unique = TRUE), on = .(Year, State) 
           ][is.na(PolicyNo), PolicyNo := 0 
           ][, .(PolicyNo = sum(PolicyNo)), by = .(Year, State) 
            ][, .(Year, State, PolicyNo = cumsum(PolicyNo))] 

上述代碼的結果:

Year State PolicyNo 
1: 2001 PA  15 
2: 2002 PA  22 
3: 2003 PA  22 
4: 2004 PA  13 
5: 2005 PA  15 

正如你所看到的,有需要幾個步驟來到期望的endresult:

  • 首先你轉換爲data.table(setDT(dat))和重塑這個爲長格式,並沒有Year
  • 刪除行然後你做出有'Year_repealed'負行的值。
  • 通過交叉連接(CJ),確保存在每種狀態的年份,並將PolicyNo列中的NA值轉換爲零。
  • 最後,您按年份總結並對結果進行累計計算。