【问题标题】:Estimating departures in a matrix估计矩阵中的偏差
【发布时间】:2014-04-14 17:50:48
【问题描述】:

我试图估计在给定时间步长(日期)内处于给定区域的人数(唯一“id”)在下一个时间步长中离开了该区域。这是数据的一小部分:

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 相加,得出每个时间步长的每个区域的出发总和。类似的东西,但在制定该函数时遇到了麻烦

【问题讨论】:

  • 你的数据很乱:id "415786" 被报告在同一天 (2007-04-01) 位于 802 和 804 区。你想怎么处理?
  • 重复是我的错误。对不起!请参阅下面的下一条评论。

标签: r loops matrix time transition


【解决方案1】:

新答案:

所以,第一步就是按照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 的第二个区域数据(如果重复)的地方。您可能想要修改它以使用另一种方法来处理混乱的数据:)

【讨论】:

  • 杰莉,非常感谢您的帮助。重复的数据是我的错误。实际数据没有这样的重复。我试图复制一个小得多的数据版本,显然我的复制很草率。我感谢你的努力!我很困惑,因为这个函数没有返回正确的信息。我需要一个函数来遍历所有 id 并告诉我在时间 t 区域 x 中有多少唯一 id 在 t+1 中离开区域 x。对不起,我没有更清楚。实际数据有 25 个区域、80 个时间段和 61 个 id。这有助于清除它吗?
  • 哎呀,我的错,我误解了你的问题..我会尝试看看我是否可以改变我的答案以使其适用于你的问题
  • 我的问题措辞不当。我非常感谢您的帮助!让我知道是否有办法让像我这样的新手以某种方式投票给你。
  • 我在想一个类似于两步函数的东西 1.) 遍历所有单独的 ID,询问是否 zone[i] in date[t] = zone[i] in date[t+1] ,如果不产生“1”并存储在矩阵中(表示离开);然后 2.) 将所有 ID 中每个区域/日期的所有 1 相加,得出每个时间步长的每个区域的出发总和。类似的东西,但在制定该函数时遇到了麻烦。
  • 是的,这是正确的做法。我会尽快更新答案,如果它完成了你可以接受的工作:)
猜你喜欢
  • 2015-12-17
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 2016-05-16
  • 1970-01-01
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
相关资源
最近更新 更多