首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于R中的移动时间窗口连接数据

基于R中的移动时间窗口连接数据
EN

Stack Overflow用户
提问于 2011-04-12 07:01:07
回答 2查看 549关注 0票数 3

我有每小时记录一次的天气数据,以及每4小时记录一次的位置数据(X,Y)。我想知道位置X,Y的温度是多少,天气数据并不是完全相同的。因此,我为每个位置编写了这个循环,以扫描天气数据,查找日期/时间中的“最近”日期/时间,并从该时间提取数据。问题是我写它的方式,对于位置#2,它扫描天气数据,但不允许分配给location#1的最近时间信息。假设位置#1和2在下午6点和6:10点在10分钟内拍摄,最近的天气时间是下午6点我不能让它允许下午6点的天气数据作为一个选项。我像这样设置它,因为我的位置数据集中有200个地点(比方说3个月后),我不希望从天气数据中的时间0开始,因为我知道最近的天气数据是为最后一个地点计算的,而且恰好也是该数据集的3个月后。下面是一些示例数据和我的代码。我不知道这是否有意义。

代码语言:javascript
复制
<h6>####Location data</h6>

<p>X   Y   DateTime <br />
1   2   4/2/2003    18:01:01
3   2   4/4/2003    17:01:33
2   3   4/6/2003    16:03:07
5   6   4/8/2003    15:03:08
3   7   4/10/2003   14:03:06
4   5   4/2/2003    13:02:00
4   5   4/4/2003    12:14:43
4   3   4/6/2003    11:00:56
3   5   4/8/2003    10:02:06</p>

<h2>2   4   4/10/2003   9:02:19</h2>

<p>Weather Data
DateTime        WndSp   WndDir  Hgt
4/2/2003 17:41:00   8.17    102.86  3462.43
4/2/2003 20:00:00   6.70    106.00  17661.00
4/2/2003 10:41:00   6.18    106.00  22000.00
4/2/2003 11:41:00   5.78    106.00  22000.00
4/2/2003 12:41:00   5.48    104.00  22000.00
4/4/2003 17:53:00   7.96    104.29  6541.00
4/4/2003 20:53:00   6.60    106.00  22000.00
4/4/2003 19:41:00   7.82    105.00  7555.00
4/4/2003 7:41:00    6.62    105.00  14767.50
4/4/2003 8:41:00    6.70    106.00  17661.00
4/4/2003 9:41:00    6.60    106.00  22000.00
4/5/2003 20:41:00   7.38    106.67  11156.67
4/6/2003 18:07:00   7.82    105.00  7555.00
4/6/2003 21:53:00   6.18    106.00  22000.00
4/6/2003 21:41:00   6.62    105.00  14767.50
4/6/2003 4:41:00    7.96    104.29  6541.00
4/6/2003 5:41:00    7.82    105.00  7555.00
4/6/2003 6:41:00    7.38    106.67  11156.67
4/8/2003 18:53:00   7.38    106.67  11156.67
4/8/2003 22:53:00   5.78    106.00  22000.00
4/8/2003 1:41:00    5.78    106.00  22000.00
4/8/2003 2:41:00    5.48    104.00  22000.00
4/8/2003 3:41:00    8.17    102.86  3462.43
4/10/2003 19:53:00  6.62    105.00  14767.50
4/10/2003 23:53:00  5.48    104.00  22000.00
4/10/2003 22:41:00  6.70    106.00  17661.00
4/10/2003 23:41:00  6.60    106.00  22000.00
4/10/2003 0:41:00   6.18    106.00  22000.00
4/11/2003 17:41:00  8.17    102.86  3462.43</p>

<h2>4/12/2003 18:41:00  7.96    104.29  6541.0</h2>

代码语言:javascript
复制
weathrow = 1
for (i in 1:nrow(SortLoc)) {
    t = 0
    while (t < 1) {
        timedif1 = difftime(SortLoc$DateTime[i], SortWeath$DateTime[weathrow], units="auto")
        timedif2 =  difftime(SortLoc$DateTime[i], SortWeath$DateTime[weathrow+1], units="auto") 
        if (timedif2 < 0) {
            if (abs(timedif1) < abs(timedif2)) {
                SortLoc$WndSp[i]=SortWeath$WndSp[weathrow]
                SortLoc$WndDir[i]=SortWeath$WndDir[weathrow]
                SortLoc$Hgt[i]=SortWeath$Hgt[weathrow]
            } else {
                SortLoc$WndSp[i]=SortWeath$WndSp[weathrow+1]
                SortLoc$WndDir[i]=SortWeath$WndDir[weathrow+1]
                SortLoc$Hgt[i]=SortWeath$Hgt[weathrow+1]
            }
            t = 1
        }
        if (abs(SortLoc$DateTime[i] - SortLoc$DateTime[i+1] < 50)) {
            weathrow=weathrow
        } else {
            weathrow = weathrow+1
            #if(weathrow = nrow(SortWeath)){t=1}
        }
    } #end while
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-14 05:32:24

您可以使用findInterval函数查找最接近的值:

代码语言:javascript
复制
# example data:
x <- rnorm(120000)
y <- rnorm(71000)
y <- sort(y) # second vector must be sorted
id <- findInterval(x, y, all.inside=TRUE) # finds position of last y smaller then x
id_min <- ifelse(abs(x-y[id])<abs(x-y[id+1]), id, id+1) # to find nearest

在您的情况下,可能需要一些as.numeric

代码语言:javascript
复制
# assumed that SortWeath is sorted, if not then SortWeath <- SortWeath[order(SortWeath$DateTime),]
x <- as.numeric(SortLoc$DateTime)
y <- as.numeric(SortWeath$DateTime)
id <- findInterval(x, y, all.inside=TRUE)
id_min <- ifelse(abs(x-y[id])<abs(x-y[id+1]), id, id+1)
SortLoc$WndSp  <- SortWeath$WndSp[id_min]
SortLoc$WndDir <- SortWeath$WndDir[id_min]
SortLoc$Hgt    <- SortWeath$Hgt[id_min]

一些附加的东西:你应该在-中向data.frame中绝对更新的循环添加值。检查此比较:

代码语言:javascript
复制
N=1000
x <- numeric(N)
X <- data.frame(x=x)
require(rbenchmark)
benchmark(
    vector = {for (i in 1:N) x[i]<-1},
    data.frame = {for (i in 1:N) X$x[i]<-1}
)
#         test replications elapsed relative
# 2 data.frame          100    4.32    22.74
# 1     vector          100    0.19     1.00

data.frame版本的速度要慢20倍以上,如果包含的行数越多,差异就越大。

因此,如果您更改脚本并首先初始化结果向量:

代码语言:javascript
复制
tmp_WndSp <- tmp_WndDir <- tmp_Hg <- rep(NA, nrow(SortLoc))

然后在循环中更新值

代码语言:javascript
复制
tmp_WndSp[i] <- SortWeath$WndSp[weathrow+1]
# and so on...

并在最后(在循环之外)更新正确的列:

代码语言:javascript
复制
SortLoc$WndSp <- tmp_WndSp
SortLoc$WndDir <- tmp_WndDir
SortLoc$Hgt <- tmp_Hgt

它应该跑得更快。

票数 1
EN

Stack Overflow用户

发布于 2011-04-12 20:51:55

以下是您可能使用的一种策略的示例。这将逐一分析天气时间,然后获取该时间与每个位置时间之间的差值的绝对值,然后获取最小的时间差值。这就解决了你向前看/向后看的问题。您的数据集似乎足够小,移动到半矢量化解决方案应该是您需要的所有速度增益,但如果不是这样,那么添加一个移动窗口应该相对简单,该窗口只通过最后一个loc.match.index周围的一些+/- N个观察值。

代码语言:javascript
复制
w <- as.POSIXct(strptime( c("4/2/2003 17:41:00","4/2/2003 20:00:00","4/2/2003 10:41:00","4/2/2003 11:41:00","4/2/2003 12:41:00"),format="%m/%d/%Y %H:%M:%S"))
l <- as.POSIXct(strptime( c("4/2/2003 18:01:01","4/2/2003 17:01:33","4/2/2003 16:03:07","4/2/2003 15:03:08","4/2/2003 14:03:06","4/2/2003 13:02:00"),format="%m/%d/%Y %H:%M:%S"))

window.size <- 5

findClosest <- function(w.i,l) {
    which.min(abs(w.i-l))
}
makeWindow <- function(loc.match.index,i,window.size,n) {
    win.max <- loc.match.index[i-1] + window.size
    if(win.max > n) {
        win.max <- n
    }
    win.min <- loc.match.index[i-1] - window.size
    if(win.min < 1) {
        win.min <- 1
    }
    return(seq(win.min,win.max))
}

loc.match.index <- integer()
n <- length(w)
# Initialize on whole vector
i <- 1
loc.match.index[i] <- findClosest(w[i],l)
# Continue on window
for(i in seq(2,n)) {
    wndw <- makeWindow(loc.match.index,i,window.size,n)
    loc.match.index[i] <- findClosest(w[i],l[wndw]) 
    # Add the start of the window back to the index that was returned
    loc.match.index[i] <- loc.match.index[i] + min(wndw)-1
}
> loc.match.index
[1] 1 1 5 5 5

仍然有一些地方可以提高效率,但考虑到比较是矢量化的,并且窗口可以调优,这应该是相当快的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5628555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档