当数据不连续时,如何在最接近值y的随机中采样n个值?
-
08-10-2019 - |
题
我有一个数据集,其中包括一个物种列表,其计数以及调查开始何时开始的日期。由于没有采样许多天,所以一天不是连续的。因此,例如,可能有鸟类在第5,6,9,10,10,15,34,39天等。我将最早的日期设置为第0天。
示例数据:
species counts day
Blue tit 234 0
Blue tit 24 5
Blue tit 45 6
Blue tit 32 9
Blue tit 6 10
Blue tit 98 15
Blue tit 40 34
Blue tit 57 39
Blue tit 81 43
..................
我需要引导此数据,并获取一个结果数据集,我在其中指定何时开始,进行什么间隔以及示例的点数。
示例:假设我随机选择第5天作为开始的一天,间隔为30,而示例的行数为2。 (但不是第35天本身)。在这种情况下,我将抓住这两行,一天是34和39。
接下来,我将30至35添加到65左右的大约65点。冲洗,重复直到到达数据集的末尾。
我已经编写了此功能来进行采样,但是它有缺陷(请参见下文):
resample <- function(x, ...) x[sample.int(length(x), ...)]
locate_points<- function(dataz,l,n) #l is the interval, n is # points to sample. This is called by another function that specifies start time among other info.
{
tlength=0
i=1
while(tlength<n)
{
low=l-i
high=l+i
if(low<=min(dataz$day)) { low=min(dataz$day) }
if(high>=max(dataz$day)) { high=max(dataz$day) }
test=resample(dataz$day[dataz$day>low & dataz$day<high & dataz$day!=l])
tlength=length(test)
i=i+1
}
test=sort(test)
k=test[1:n]
return (k)
}
我需要帮助的两个问题:
虽然我的功能确实返回所需的点数,但并非围绕我的搜索值。是有道理的,因为随着我变得更宽,我会得到更多的观点,当我对这些分类并选择第一个N时,它们往往不是低值。
其次,如何将实际行分出来?现在我有另一个功能可以使用
which
, , 然后rbind
'将这些行一起在一起。似乎应该有更好的方法。
谢谢!
解决方案
那样的事情如何:
day = 1:1000
search = seq(from=5, to=max(day), by=30)
x = sort(setdiff(day, search))
pos = match(x[unlist(lapply(findInterval(search, x), seq, len=2))], day)
day[pos]
要从数据中获取行。FRAME只需将其征用:
rows = data[pos, ]
这可能比Unlist/Lapply/Seq组合要干净一些:
pos = match(x[outer(c(0, 1), findInterval(search, x), `+`)], day)
另请注意,如果您想要一个较大的窗口(例如说4),那只是回去的问题:
pos = match(x[outer(-1:2, findInterval(search, x), `+`)], day)
其他提示
喜欢查尔斯的解决方案,该解决方案非常适合n = 2的情况。 las,它不能扩展到较大的窗户。它仍然具有OP:较大的窗口所描述的问题,因此选择并非围绕搜索值。给定n甚至是,我想出了以下解决方案,基于查尔斯的想法。
该功能控制边界。如果有100天,下一个中点是第二天,则为4的窗口意味着您选择索引101,这给 NA
. 。此功能会移动窗口,因此所有选定的索引都位于原始数据中。这也具有取决于开始值的副作用(st
), 长度(l
)和窗口(n
)开始和结束的值两次被选中两次。长度应始终至少是窗口尺寸的两倍。
该函数的输出是引导程序样本的索引。它可以用作 pos
查尔斯在向量和数据框架上的变量。
bboot <- function(day,st,l,n){
mid <- seq(st,max(day),by=l)
x <-sort(setdiff(day,mid))
lx <- length(x)
id <- sapply(mid,
function(y){
m <- match(T,x>y)
seq(
from=min( lx-n, max(1,m+(-n/2)) ),
to=min( lx, max(n,m+(n/2-1)) )
)
}
)
pos <- match(x[id],day)
return(pos)
}
然后
> day <- sample(1:100,50)
> sample.rownr <- bboot(day,10,20,6)
> sort(day)
[1] 3 4 5 7 9 10 13 15 16 18 19 21 22 24 25 26 27 28 29
[20] 30 31 32 35 36 38 40 45 49 51 52 54 55 58 59 62 65 69 72 73
[40] 74 80 84 87 88 91 92 94 97 98 99
> day[sample.rownr]
[1] 5 7 9 13 15 16 27 28 29 31 32 35 40 45 49 51 52 54 62
[20] 65 69 72 73 74 84 87 88 91 92 94
>
编辑:关于时间序列的自举,您应该通过 cran tastview on Time序列, ,特别是有关重采样的部分。对于不规则时间序列, zoo
软件包还提供了一些其他方便的功能。