首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dynamically Elements WIthin a R循环

Dynamically Elements WIthin a R循环
EN

Stack Overflow用户
提问于 2011-11-18 04:46:41
回答 3查看 3.4K关注 0票数 1

好的,伙计们,根据要求,我会添加更多的信息,这样你们就能理解为什么简单的向量运算是不可能的。这不容易用几句话来解释,但让我们来看看。我在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):

代码语言:javascript
复制
 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]){

代码语言:javascript
复制
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,]

感谢任何人的帮助!感谢弗朗西斯科

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-11-18 05:53:53

在你的情况下,我不会担心在你走的时候删除点,跳过是关键。我也不会像你那样一块一块地编出一个新的data.frame。这两件事都会大大减慢你的速度。有一个选择向量要高效得多(可能是data.frame的一部分,事先设置为FALSE )。

代码语言:javascript
复制
df$sel <- FALSE

现在,在遍历时,为要保留的每个项将df$sel设置为TRUE。当你找到10的时候,跳到下一个单元格。删除这些值会耗费时间和内存,也会慢慢增加一个新的data.frame。当您完成所有这些操作之后,您只需根据选择列选择数据即可。

代码语言:javascript
复制
df <- df[ df$sel, ]

(或者可能会在此时复制data.frame )

您可能还希望使用dist函数来计算距离矩阵。

来自?dist

“此函数计算并返回使用指定距离度量计算的距离矩阵,以计算数据矩阵的行之间的距离。”

票数 4
EN

Stack Overflow用户

发布于 2011-11-18 05:09:38

我假设您正在做一些足够复杂的事情,以至于实际上需要使用for循环……

所以这里有一个相当简单的方法:首先收集要删除(或保留)的行,然后删除这些行。通常,这也会快得多,因为您不需要在每次循环迭代时修改data.frame

代码语言:javascript
复制
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循环部分更改为:

代码语言:javascript
复制
for(i in seq_len(nrow(df))) {
  if (keepRows[i]) {
      rows <- findRowsToDelete(df[keepRows, ], df[i,]) 
      keepRows[rows] <- FALSE
  }
}
票数 2
EN

Stack Overflow用户

发布于 2011-11-18 05:04:18

我不是很清楚你为什么要循环。如果你能描述你正在检查的是哪种条件,也许有一种很好的矢量化方法。

然而,作为一种非常简单的修复方法,您是否考虑过向后遍历数据帧?

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

https://stackoverflow.com/questions/8174067

复制
相关文章

相似问题

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