2014-02-27 106 views
2

我有两个关于交通流量的数据表。我试图(最终)通过里程碑将它们组合成线性的交通情节。例如:如何在R中对此进行矢量化处理

mileposts <- structure(list(city = c("city1", "city2", "city3", "city4"), 
milepost = c(0L, 50L, 120L, 250L)), .Names = c("city", "milepost" 
), class = "data.frame", row.names = c("1", "2", "3", "4")) 

    city milepost 
1 city1  0 
2 city2  50 
3 city3  120 
4 city4  250 


traffic <- structure(list(citypair = c("city1-city2", "city2-city4", "city1-city3", 
"city1-city4", "city3-city4"), traffic = c(610L, 23L, 139L, 88L, 
17L), origmp = c(0L, 50L, 0L, 0L, 120L), destmp = c(50L, 250L, 
120L, 250L, 250L)), .Names = c("citypair", "traffic", "origmp", 
"destmp"), class = "data.frame", row.names = c("1", "2", "3", 
"4", "5")) 

    citypair  traffic origmp destmp 
1 city1-city2  610  0  50 
2 city2-city4  23  50  250 
3 city1-city3  139  0  120 
4 city1-city4  88  0  250 
5 city3-city4  17  120  250 

我想是添加到“里程碑”表中,列出所有的交通开始在或经过该城市一列“体积”(城市为了去1-2 -3-4)。例如,city3的音量将是来自流量[c(2,4,5),2]的值的总和。

我该怎么做?我知道它一定是某种循环。我尝试了一个循环,在traffic$origmp[i] >= mileposts$mileposttraffic$destmp[i] <= mileposts$milepost的条件下添加traffic$traffic to mileposts$vol中的值,但我得到的错误是"the condition has length > 1 and only the first element will be used"。但是,如果我将整个事件围绕[j]维度包装在mileposts$milepost上,整个运行变得非常慢。有关如何有效加速/代码的任何建议?更多地一般来说,我想问的是如何以有效的方式(即不循环遍历两个数据帧的每一行)使用两个数据帧之间的数据执行条件操作。谢谢!

+0

我们究竟如何,都应该知道所有的城市“开始在或穿过那个城市。“? –

+0

@IShouldBuyABoat - 我对city1-city2-city3-city4做了一个很大的假设:理想情况下这应该被指定为使其成为一个通用的解决方案。 – thelatemail

+0

@thelatemail是的,他们从城市1-4顺序进行。对不起,没有更清楚。 – user3358547

回答

0

有了您的两个表 - milepoststraffic已经在内存中,我能得到你想要用下面的代码的结果 -

library(data.table) 

# building index of which route traffic is to be associated with which city 
uniquecities <- unique(mileposts$milepost) 
uniqueCityCombns <- data.table(expand.grid(uniquecities,uniquecities,uniquecities)) 
setnames(uniqueCityCombns, c('origmp','destmp','milepost')) 
uniqueCityCombns <- uniqueCityCombns[origmp < destmp & milepost < destmp] 
uniqueCityCombns <- data.table(uniqueCityCombns <- uniqueCityCombns[origmp <= milepost]) 

# calculating traffic passing through the city 
uniqueCityCombnsTrf <- merge(uniqueCityCombns,traffic, by = c('origmp','destmp')) 
uniqueCityCombnsTrf <- uniqueCityCombnsTrf [,list(traffic = sum(traffic)), by = 'milepost'] 
uniqueCityCombnsTrf <- merge(uniqueCityCombnsTrf , mileposts, by = 'milepost') 

输出 -

> uniqueCityCombnsTrf 
    milepost traffic city 
1:  0  837 city1 
2:  50  250 city2 
3:  120  128 city3 
1

这有点令人费解,但它的工作原理:

cityorder <- c("city1","city2","city3","city4") 
through <- lapply(strsplit(traffic$citypair,"-"),match,cityorder) 
through <- lapply(through,function(x) seq(x[1],x[2]-1)) 

citymatch <- sapply(mileposts$city, grep, cityorder) 
sum.ids <- lapply(citymatch, function(x) sapply(through, function(y) x %in% y)) 
mileposts$traffic <- sapply(sum.ids, function(x) sum(traffic$traffic[x])) 

# city milepost traffic 
#1 city1  0  837 
#2 city2  50  250 
#3 city3  120  128 
#4 city4  250  0 

结果检查出与预期结果“请分享帮助的音量会从流量值的总和[C(2,4,5),2]”

sum(traffic[c(2, 4, 5),2]) 
#[1] 128 
0
traffic$start <- as.numeric(gsub("city|-city.+$", "", traffic$citypair)) 
traffic$end <- as.numeric(gsub("city[[:digit:]]*|-city", "", traffic$citypair)) 
sapply(mileposts$city, function(cit) {n=as.numeric(sub("city","",cit)) 
        sum(traffic$traffic*((n >= traffic$start) & n < traffic$end))}) 
#--------- 
city1 city2 city3 city4 
    837 250 128  0