【发布时间】:2012-12-20 23:40:21
【问题描述】:
我有一个数据表,其中 nrow 约为 100 万或 2,ncol 约为 200。
一行中的每个条目都有一个与之关联的坐标。
数据的一小部分:
[1,] -2.80331471 -0.8874522 -2.34401863 -3.811584 -2.1292443
[2,] 0.03177716 0.2588624 0.82877467 1.955099 0.6321881
[3,] -1.32954665 -0.5433407 -2.19211837 -2.342554 -2.2142461
[4,] -0.60771429 -0.9758734 0.01558774 1.651459 -0.8137684
前 4 行的坐标:
9928202 9928251 9928288 9928319
我想要的是一个给定数据和窗口大小的函数,它将返回一个大小相同的数据表,并在每列上应用一个平均滑动窗口。或者换句话说 - 对于每个行条目 i 它会找到坐标在 coords[i]-windsize 和 coords[i]+windsize 之间的条目,并将初始值替换为其中的值的平均值间隔(每列分别)。
速度是这里的主要问题。
这是我第一次使用这种功能。
doSlidingWindow <- function(intensities, coords, windsize) {
windHalfSize <- ceiling(windsize/2)
### whole range inds
RANGE <- integer(max(coords)+windsize)
RANGE[coords] <- c(1:length(coords)[1])
### get indeces of rows falling in each window
COORDS <- as.list(coords)
WINDOWINDS <- sapply(COORDS, function(crds){ unique(RANGE[(crds-windHalfSize):
(crds+windHalfSize)]) })
### do windowing
wind_ints <- intensities
wind_ints[] <- 0
for(i in 1:length(coords)) {
wind_ints[i,] <- apply(as.matrix(intensities[WINDOWINDS[[i]],]), 2, mean)
}
return(wind_ints)
}
最后一个 for 循环之前的代码非常快,它为我提供了每个条目需要使用的索引列表。然而,一切都崩溃了,因为我需要将 for 循环研磨一百万次,获取我的数据表的子集,并确保我有不止一行能够同时处理所有的列。
我的第二种方法是将实际值粘贴在 RANGE 列表中,用零填充空白,然后从 zoo 包中进行 rollmean,对每一列重复。但这是多余的,因为 rollmean 会遍历所有间隙,我最终只会使用原始坐标的值。
非常感谢您在不使用 C 的情况下使其更快的任何帮助。
【问题讨论】:
-
我不是
zoo的专家,但你确定使用rollmean(data,fill=NA)不够快吗? -
如果你还是将数据存储在数据库中:使用 PostgreSQL 的数据库中的 sqldf 可以运行窗口统计。
-
致卡尔:rollmean 确实够快。但它不能处理任意坐标上的间隔。它只是在时间序列上使用固定的窗口大小,并且时间序列有固定的间隔。在这种情况下,间隔不是规则的,两点之间的空间可以是任意的。因此,如果我用 zoo 包的零填充所有空白 - 我将得到一个长度约为 5 亿的向量。在数据帧上使用 rollmean 是很痛苦的,尤其是当我只需要使用 rollmean 计算的 500 个中的几百万个时。
-
在最后一个循环中最好将行改为:
wind_ints[i,] <- apply(matrix(intensities[WINDOWINDS[[i]],], ncol=ncol(intensities)), 2, mean)。当窗口中只有一行时,您的代码会导致错误的结果。
标签: r coordinates sliding-window