2016-12-03 66 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值转换为零。
  • 最后,您按年份总结并对结果进行累计计算。