好的,伙计们,根据要求,我会添加更多的信息,这样你们就能理解为什么简单的向量运算是不可能的。这不容易用几句话来解释,但让我们来看看。我在2D空间上有大量的点。我将我的空间划分在一个给定分辨率的网格中,比如100m。我不确定这是否是强制的(欢迎任何替代)的主循环是遍历包含至少2个点的每个单元格/像素(目前我在包spatstat中使用方法quadratcount )。在这个循环中,对于每个非空的单元格,我只能找到并保留最多10对相距不超过3米的男女对。3米的缓冲区可以使用spatstat中的"disc“功能来完成。要选择位于缓冲区内的点,可以使用SDMTools包中的pnt.in.poly方法。所有这些都是因为像素有一个不能超过的最大容量。因为在每个单元格中可能有成百上千个点,所以我正在尝试找到一种聪明的方法来使用另一个循环/类似的方法:1)一次遍历每个点2)创建一个缓冲区一个具有不同性别的选择点3)将最接近的男女(0-1)对保存在另一个数据帧(称为new_colonies)中4)从数据帧中删除那些点,这样它就会缩小,我不再需要考虑它们5)一旦新的数据帧达到10行,就停止一切并转到下一个单元格(因此跳过所有剩余的点)。下面是我开发的在每个单元中运行的代码(现在太长了):
头(df,20):
X Y Sex ID
2 583058.2 2882774 1 1
3 582915.6 2883378 0 2
4 582592.8 2883297 1 3
5 582793.0 2883410 1 4
6 582925.7 2883397 1 5
7 582934.2 2883277 0 6
8 582874.7 2883336 0 7
9 583135.9 2882773 1 8
10 582955.5 2883306 1 9
11 583090.2 2883331 0 10
12 582855.3 2883358 1 11
13 582908.9 2883035 1 12
14 582608.8 2883715 0 13
15 582946.7 2883488 1 14
16 582749.8 2883062 0 15
17 582906.4 2883317 0 16
18 582598.9 2883390 0 17
19 582890.2 2883413 0 18
20 582752.8 2883361 0 19
21 582953.1 2883230 1 20在每个单元格中,我必须根据我上面解释的内容运行一些东西。
for(i in 1:dim(df)[1]){
new_colonies <- data.frame(ID1=0,ID2=0,X=0,Y=0)
discbuff <- disc(radius, centre=c(df$X[i], df$Y[i]))
#define the points and polygon
pnts = cbind(df$X[-i],df$Y[-i])
polypnts = cbind(x = discbuff$bdry[[1]]$x, y = discbuff$bdry[[1]]$y)
out = pnt.in.poly(pnts,polypnts)
out$ID <- df$ID[-i]
if (any(out$pip == 1)) {
pnt.inBuffID <- out$ID[which(out$pip == 1)]
cond <- df$Sex[i] != df$Sex[pnt.inBuffID]
if (any(cond)){
eucdist <- sqrt((df$X[i] - df$X[pnt.inBuffID][cond])^2 + (df$Y[i] - df$Y[pnt.inBuffID][cond])^2)
IDvect <- pnt.inBuffID[cond]
new_colonies_temp <- data.frame(ID1=df$ID[i], ID2=IDvect[which(eucdist==min(eucdist))],
X=(df$X[i] + df$X[pnt.inBuffID][cond][which(eucdist==min(eucdist))]) / 2,
Y=(df$Y[i] + df$Y[pnt.inBuffID][cond][which(eucdist==min(eucdist))]) / 2)
new_colonies <- rbind(new_colonies,new_colonies_temp)
if (dim(new_colonies)[1] == maxdensity) break
}
}
}
new_colonies <- new_colonies[-1,]感谢任何人的帮助!感谢弗朗西斯科
发布于 2011-11-18 05:53:53
在你的情况下,我不会担心在你走的时候删除点,跳过是关键。我也不会像你那样一块一块地编出一个新的data.frame。这两件事都会大大减慢你的速度。有一个选择向量要高效得多(可能是data.frame的一部分,事先设置为FALSE )。
df$sel <- FALSE现在,在遍历时,为要保留的每个项将df$sel设置为TRUE。当你找到10的时候,跳到下一个单元格。删除这些值会耗费时间和内存,也会慢慢增加一个新的data.frame。当您完成所有这些操作之后,您只需根据选择列选择数据即可。
df <- df[ df$sel, ](或者可能会在此时复制data.frame )
您可能还希望使用dist函数来计算距离矩阵。
来自?dist
“此函数计算并返回使用指定距离度量计算的距离矩阵,以计算数据矩阵的行之间的距离。”
发布于 2011-11-18 05:09:38
我假设您正在做一些足够复杂的事情,以至于实际上需要使用for循环……
所以这里有一个相当简单的方法:首先收集要删除(或保留)的行,然后删除这些行。通常,这也会快得多,因为您不需要在每次循环迭代时修改data.frame。
df <- generateTheDataFrame()
keepRows <- rep(TRUE, nrow(df))
for(i in seq_len(nrow(df))) {
rows <- findRowsToDelete(df, df[i,])
keepRows[rows] <- FALSE
}
# Delete afterwards
df <- df[keepRows, ]如果您确实需要在每次迭代中处理缩小的数据,只需将...and循环部分更改为:
for(i in seq_len(nrow(df))) {
if (keepRows[i]) {
rows <- findRowsToDelete(df[keepRows, ], df[i,])
keepRows[rows] <- FALSE
}
}发布于 2011-11-18 05:04:18
我不是很清楚你为什么要循环。如果你能描述你正在检查的是哪种条件,也许有一种很好的矢量化方法。
然而,作为一种非常简单的修复方法,您是否考虑过向后遍历数据帧?
https://stackoverflow.com/questions/8174067
复制相似问题