2011-03-24 70 views
9

我有一个文件(位置)具有x,y坐标和日期/时间标识。我想从具有“相似”日期/时间变量和协变量(温度和风速)的第二个表格(天气)获取信息。诀窍是两个表中的日期/时间不完全相同。我想从位置数据中选择最接近的天气数据。我知道我需要做一些循环和那个。基于R中的日期/时间范围加入数据

Example location         example weather 

x y  date/time       date/time   temp  wind 
1 3  01/02/2003 18:00     01/01/2003 13:00  12   15 
2 3  01/02/2003 19:00     01/02/2003 16:34  10   16 
3 4  01/03/2003 23:00     01/02/2003 20:55  14   22 
2 5  01/04/2003 02:00     01/02/2003 21:33  14   22 
              01/03/2003 00:22  13   19 
              01/03/2003 14:55  12   12 
              01/03/2003 18:00  10   12 
              01/03/2003 23:44  2   33 
              01/04/2003 01:55  6   22 

所以最终的输出将与正确的“最佳”匹配的气象数据中的位置数据

x y  datetime    datetime   temp  wind 
1 3  01/02/2003 18:00 ---- 01/02/2003 16:34  10   16 
2 3  01/02/2003 19:00 ---- 01/02/2003 20:55  14   22 
3 4  01/03/2003 23:00 ---- 01/03/2003 00:22  13   19    
2 5  01/04/2003 02:00 ---- 01/04/2003 01:55  6   22 

任何建议,从哪里开始的表?我试图在R

+2

我希望你能在没有传统循环的情况下解决这个问题。来自申请家庭的一个声明加上一个约()可能会有好处。建议从哪里开始?给我们一些适当的数据来处理。而不是粘贴文本,在R中构建数据,然后在这里粘贴dput()的结果,以便我们可以轻松地重建数据并编写一些可以测试的代码。 – Andrie 2011-03-24 21:47:35

+1

为什么位置的第3行加入天气第5行?是不是最接近01/03/2003 23:00的天气第8排? – 2011-03-24 21:57:23

+0

@ Matthew - 你是对的,这是一个在飞行中产生数据的错误 – Kerry 2011-03-24 22:52:47

回答

5

我需要把这些数据作为数据和时间分开,然后粘贴和格式

location$dt.time <- as.POSIXct(paste(location$date, location$time), 
           format="%m/%d/%Y %H:%M") 

与同为weather

然后在location的date.time每个值,找到条目weather具有最低绝对值的时间差:

sapply(location$dt.time, function(x) which.min(abs(difftime(x, weather$dt.time)))) 
# [1] 2 3 8 9 
cbind(location, weather[ sapply(location$dt.time, 
         function(x) which.min(abs(difftime(x, weather$dt.time)))), ]) 

    x y  date time    dt.time  date time temp wind    dt.time 
2 1 3 01/02/2003 18:00 2003-01-02 18:00:00 01/02/2003 16:34 10 16 2003-01-02 16:34:00 
3 2 3 01/02/2003 19:00 2003-01-02 19:00:00 01/02/2003 20:55 14 22 2003-01-02 20:55:00 
8 3 4 01/03/2003 23:00 2003-01-03 23:00:00 01/03/2003 23:44 2 33 2003-01-03 23:44:00 
9 2 5 01/04/2003 02:00 2003-01-04 02:00:00 01/04/2003 01:55 6 22 2003-01-04 01:55:00 

cbind(location, weather[ 
        sapply(location$dt.time, 
        function(x) which.min(abs(difftime(x, weather$dt.time)))), ])[ #pick columns 
          c(1,2,5,8,9,10)] 

    x y    dt.time temp wind   dt.time.1 
2 1 3 2003-01-02 18:00:00 10 16 2003-01-02 16:34:00 
3 2 3 2003-01-02 19:00:00 14 22 2003-01-02 20:55:00 
8 3 4 2003-01-03 23:00:00 2 33 2003-01-03 23:44:00 
9 2 5 2003-01-04 02:00:00 6 22 2003-01-04 01:55:00 

我的回答似乎有点不同比其他读者已经质疑您的手工匹配能力。

+0

哈哈哈!人为错误!从而需要电脑的动画过程。 – Kerry 2011-03-24 23:47:31

5

一个快捷方式可能是使用data.table。 如果你创建了两个data.table的X和Y,都与钥匙,那么语法是:

X[Y,roll=TRUE] 

我们称之为一个滚动加入因为我们推出的X普遍观察着该行匹配Y.请参阅?data.table中的示例和简介小插曲。

另一种方法做到这一点是动物园包有locf(最后观察结转),也可能是其他包。

我不确定你的意思是最接近的位置或时间。如果位置,并且该位置是x,y坐标,那么您将需要在2D空间中进行一些距离度量。 data.table只能做到“最接近”的单变量按时间。虽然第二次读到你的问题,但你确实认为你的意思是最接近的。

编辑:现在看到示例数据。 data.table不会一步做到这一点,因为尽管它可以向前或向后滚动,但它不会滚到最近。你可以用一个额外的步骤来做到这一点,使用哪一个= TRUE,然后测试流行之后的那个实际上是否更接近。

+0

谢谢,我会研究一下,看看它做得更好还是更快,因为到目前为止,这是我所做的一些东西,我看到了MySQL的脚本 为**(我在1:nrow(LOC)){ \t指数= which.min(ABS(LOC $ DateTime的[I] - 天气$ DATETIME)) 禄$ WndSp [i] = weather $ WndSp [index] } ** – Kerry 2011-03-24 22:47:01