估算矩阵中的偏差

时间:2014-04-14 17:50:48

标签: r loops matrix time transition

我试图估计在给定时间步骤(日期)中给定区域中有多少个人(唯一" id" s),在下一个时间步骤中离开该区域。这是数据的一小部分:

zone   date            id
802 2007-01-01       453444
803 2007-01-01       407680
803 2007-01-01       415786
804 2007-02-01       407680
802 2007-02-01       453444
802 2007-03-01       415786
804 2007-03-01       407680
802 2007-04-01       415786
802 2007-04-01       407680
804 2007-04-01       453444
801 2007-05-01       453444
804 2007-05-01       407680
804 2007-05-01       415786
804 2007-06-01       453444
801 2007-06-01       415786
804 2007-06-01       407680
803 2007-07-01       407680
803 2007-07-01       453444
804 2007-07-01       415786

所以我的问题是,我如何估计这些离开?我正在尝试创建一个矩阵,看起来像下面的每个日期/区域总和的个体数量。非常感谢您提供的任何帮助。

        zone   2005-07-01   2005-08-01   2005-09-01 
1       103          0          1          0      
2       106          0          0          3        
3       107          0          0          0       
4      1603          0          0          0        
5      1607          0          0          0        
6      2204          0          0          0         
7      2206          0          3          1       
8      2209          0          0          0        
9      3106          0          0          0         
10     3804          0          0          0         
11     3806          0          0          0   

我正在思考类似于两步功能的事情1.)遍历所有个别ID,询问date [t]中的zone [i] = date [t + 1]中的zone [i],如果不会产生" 1"并存储在一个矩阵中(表示离开);然后2.)对所有ID中的每个区域/日期的所有1进行求和,得出每个时间步长的每个区域的离开总和。这样的事情,但在制定这个功能时遇到了麻烦

1 个答案:

答案 0 :(得分:0)

新答案:

因此,第一步是按idzone对数据进行分组,并计算每次离开的次数。这可以通过以下方式完成:

all.dates = data.frame(date=unique(zz$date))
n=nrow(all.dates)

bool.list = by(data=zz, INDICES=list(zz$zone, zz$id), FUN=function(x){
  xx = merge(x,all.dates,by=c('date'),all=T)
  xx$id[is.na(xx$id)] = 0
  return(diff(xx$id)<0)
  })

返回指示离开的列表:

> bool.list
: 801
: 407680
[1] FALSE FALSE  TRUE FALSE FALSE FALSE
-------------------------------------------------------------------------- 
: 802
: 407680
[1] FALSE FALSE FALSE  TRUE FALSE FALSE
-------------------------------------------------------------------------- 
: 803
: 407680
[1]  TRUE FALSE FALSE FALSE FALSE FALSE
-------------------------------------------------------------------------- 
: 804
: 407680
[1] FALSE  TRUE FALSE FALSE FALSE  TRUE
-------------------------------------------------------------------------- 
: 801
: 415786
[1] FALSE FALSE FALSE FALSE FALSE  TRUE
-------------------------------------------------------------------------- 
[...]

此列表可以轻松转换为矩阵:

tmp = matrix(unlist(bool.list),ncol=nrow(all.dates)-1,byrow=T)
colnames(tmp) = all.dates$date[2:nrow(all.dates)]
rownames(tmp) = rep(rownames(bool.list), length(colnames(bool.list)))

返回:

> tmp
    2007-02-01 2007-03-01 2007-04-01 2007-05-01 2007-06-01 2007-07-01
801      FALSE      FALSE       TRUE      FALSE      FALSE      FALSE
802      FALSE      FALSE      FALSE       TRUE      FALSE      FALSE
803       TRUE      FALSE      FALSE      FALSE      FALSE      FALSE
804      FALSE       TRUE      FALSE      FALSE      FALSE       TRUE
801      FALSE      FALSE      FALSE      FALSE      FALSE       TRUE
802      FALSE      FALSE      FALSE       TRUE      FALSE      FALSE
803       TRUE      FALSE       TRUE      FALSE      FALSE      FALSE
804      FALSE      FALSE      FALSE      FALSE       TRUE      FALSE
801      FALSE      FALSE      FALSE      FALSE       TRUE      FALSE
802      FALSE       TRUE      FALSE      FALSE      FALSE      FALSE
803      FALSE      FALSE      FALSE      FALSE      FALSE      FALSE
804      FALSE      FALSE      FALSE       TRUE      FALSE       TRUE

第二步是折叠具有相同ID的所有行,并计算TRUE值的数量。这可以通过以下方式完成:

result = aggregate(tmp,list(rownames(tmp)),FUN=sum)

返回:

> result
  Group.1 2007-02-01 2007-03-01 2007-04-01 2007-05-01 2007-06-01 2007-07-01
1     801          0          0          1          0          1          1
2     802          0          1          0          2          0          0
3     803          2          0          1          0          0          0
4     804          0          1          0          1          1          2

应该是理想的答案。


旧回答:

这是我最好的猜测,只要您没有指定如何处理重复数据:

# we extract all the dates:
# they will define the number of columns of the returned matrix 
all.dates = data.frame(date=unique(zz$date))

bool.list = by(data=zz, INDICES=list(zz$id), FUN=function(x){
  if (any(duplicated(x$date))) {
    x = x[!duplicated(x$date),]
  }
  # we complete so we have all dates represented, for each ID and each zone
  xx = merge(x,all.dates,all=T)
  return(diff(xx$zone)==0)
}
)

# we build the matrix from the list vectors
r = matrix(unlist(tst),ncol=nrow(all.dates)-1,nrow=length(names(tst)),byrow=T)

# some cosmetic job
colnames(r) = all.dates$date[2:nrow(all.dates)]
rownames(r) = names(bool.list)

对于您的示例,这将返回:

> r
       2007-02-01 2007-03-01 2007-04-01 2007-05-01 2007-06-01 2007-07-01
407680      FALSE      FALSE      FALSE      FALSE       TRUE      FALSE
415786         NA         NA      FALSE       TRUE      FALSE      FALSE
453444       TRUE         NA         NA      FALSE      FALSE      FALSE

您可能希望将NA替换为对您有意义的任何值(TRUEFALSE

注意部分:

  if (any(duplicated(x$date))) {
    x = x[!duplicated(x$date),]
  }

这是我删除相同date和相同id的第二个区域数据的地方,如果重复的话。您可能希望修改它以使用另一种方法处理凌乱的数据:)