选择唯一的非重复值

时间:2015-02-02 22:22:01

标签: r select unique

我有一些2004 - 2007年的面板数据,我想根据独特的值来选择。更确切地说,我试图在整个期间找出各个商店的出入口。数据样本:

 store year    rev space  market
     1 2004 110000  1095     136
     1 2005 110000  1095     136
     1 2006 110000  1095     136
     1 2007 120000  1095     136
     2 2004  35000   800     136
     3 2004  45000  1000     136
     3 2005  45000  1000     136
     3 2006  45000  1000     136
     3 2007  45000  1000     136
     4 2005  17500   320     136
     4 2006  17500   320     136
     4 2007  17500   320     136
     5 2005  45000   580     191
     5 2006  45000   580     191
     5 2007  45000   580     191
     6 2004   7000   345     191
     6 2005   7000   345     191
     6 2006   7000   345     191
     7 2007  10000   500     191

因此,例如我想知道在整个期间有多少商店退出市场,这应该是这样的:

 store year   rev space  market
     2 2004 35000   800     136
     6 2006  7000   345     191

除了有多少商店进入市场,这意味着:

 store year    rev space  market
     4 2005  17500   320     136
     5 2005  45000   580     191
     7 2007  10000   500     191

更新 我没有说它还应该承担现有的商店,例如:

 store year    rev  space  market
     1 2004 110000   1095     136
     1 2005 110000   1095     136
     1 2006 110000   1095     136
     1 2007 120000   1095     136     
     3 2004  45000   1000     136
     3 2005  45000   1000     136
     3 2006  45000   1000     136
     3 2007  45000   1000     136

因为即时通讯,对R来说很新,我一直在努力做到这一点,即使是逐年也是如此。有什么建议?

2 个答案:

答案 0 :(得分:5)

使用data.table包,如果您data.frame被调用df

dt = data.table(df)
exit = dt[,list(ExitYear = max(year)),by=store]
exit = exit[ExitYear != 2007] #Or whatever the "current year" is for this table

enter = dt[,list(EntryYear = min(year)),by=store]
enter = enter[EntryYear != 2003]

<强>更新

要获取所有列而不仅仅是年份和商店,您可以执行以下操作:

exit = dt[,.SD[year == max(year)], by=store]
exit[year != 2007]
   store year   rev space market
1:     2 2004 35000   800    136
2:     6 2006  7000   345    191

答案 1 :(得分:3)

仅使用基本R函数,这非常简单:

> subset(aggregate(df["year"],df["store"],max),year!=2007)
  store year
2     2 2004
6     6 2006

> subset(aggregate(df["year"],df["store"],min),year!=2004)
  store year
4     4 2005
5     5 2005
7     7 2007

或使用公式语法:

> subset(aggregate(year~store,df,max),year!=2007)
  store year
2     2 2004
6     6 2006

> subset(aggregate(year~store,df,min),year!=2004)
  store year
4     4 2005
5     5 2005
7     7 2007

更新汇总无法获取所有列,因此我们可以使用base“by”代替。在重新组装阵列时并不聪明:

Filter(function(x)x$year!=2007,by(df,df$store,function(s)s[s$year==max(s$year),]))

$`2`
  store year   rev space market
5     2 2004 35000   800    136

$`6`
   store year  rev space market
18     6 2006 7000   345    191

所以我们需要采取这一步 - 让我们构建一个小包装器:

by2=function(x,c,...){Reduce(rbind,by(x,x[c],simplify=FALSE,...))}

现在改用它:

> subset(by2(df,"store",function(s)s[s$year==max(s$year),]),year!=2007)
   store year   rev space market
5      2 2004 35000   800    136
18     6 2006  7000   345    191

我们可以通过创建一个函数来进一步阐明这一点,该函数用于获取具有特定列的stat(min或max)的行:

statmatch=function(column,stat)function(df){df[df[column]==stat(df[column]),]}

> subset(by2(df,"store",statmatch("year",max)),year!=2007)
   store year   rev space market
5      2 2004 35000   800    136
18     6 2006  7000   345    191

Dplyr

使用所有这些彼此不相似的基本函数会在一段时间后开始变得繁琐,所以学习和使用优秀(和高性能)dplyr软件包是个好主意:

> df %>% group_by(store) %>%
         arrange(-year) %>% slice(1) %>%
         filter(year != 2007) %>% ungroup

Source: local data frame [2 x 5]

  store year   rev space market
1     2 2004 35000   800    136
2     6 2006  7000   345    191

> df %>% group_by(store) %>% 
         arrange(+year) %>% slice(1) %>% 
         filter(year != 2004) %>% ungroup

Source: local data frame [3 x 5]

  store year   rev space market
1     4 2005 17500   320    136
2     5 2005 45000   580    191
3     7 2007 10000   500    191

注意这里不需要取消组合,但是将表格放回默认状态以进行进一步计算。