2010-10-16 6 views
2

У меня есть набор данных, который включает в себя список видов, их подсчет и дневной счет с момента начала опроса. Поскольку многие дни не были отобраны, день не является непрерывным. Так, например, на день 5,6,9,10,15,34,39 и так далее могут быть птицы. Я установил самую раннюю дату, чтобы день 0.Как выбрать n значений в случайном порядке, ближайших к значению y, когда данные не являются непрерывными?

Пример данные:

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. Это означает, что я начну с 5, добавлю к нему 30 и ищу 2 строки около 35 дней (но не сам день 35). В этом случае я возьму два ряда, где день равен 34 и 39.

Далее Я добавляю от 30 до 35 и искал два очка вокруг 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) 
} 

Две проблемы, мне нужна помощь с:

  1. Хотя моя функция не возвращать желаемое количество точек, оно не сосредоточено вокруг моего значения поиска. Имеет смысл, потому что, когда я расширяюсь, я получаю больше очков, и когда я сортирую их и выбираю первое n, они, как правило, не являются низкими значениями.

  2. Во-вторых, как получить фактические строки? На данный момент у меня есть еще одна функция, чтобы найти эти строки, используя which, затем rbind 'объединив эти строки. Похоже, что должен быть лучший способ.

спасибо!

+0

Я не знаю, понимаю ли вы вас правильно, но кажется, что ваша функция не делает то, что вы описываете. Где именно вы указываете свой интервал, который добавляется каждый раз? Это полезно, если добавить некоторые комментарии, объясняющие, что такое l, n и так далее. –

+0

@Joris Эта функция имеет другую оболочку, указывающую время начала. Я сделал несколько комментариев к приведенному выше коду. – Maiasaura

+0

Это кажется странным способом сделать выборку ваших данных. Какова ваша основная мотивация? – hadley

ответ

1

Как о чем-то вроде следующего:

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] 

Чтобы получить строки из вашего data.frame только подмножество его:

rows = data[pos, ] 

Это может быть немного чище, чем unlist/lapply/seq combo:

pos = match(x[outer(c(0, 1), findInterval(search, x), `+`)], day) 

отметить также, что если вы хотите увеличить окно (например, говорят, 4), его просто вопрос о возвращении немного:

pos = match(x[outer(-1:2, findInterval(search, x), `+`)], day) 
+0

высоко ценится, Чарльз! Я многому научился из вашего примера. веселит. – Maiasaura

+0

Спасибо, рад, что это помогло. На самом деле это кажется более сложным, чем я ожидал - вероятно, есть более простой способ ... – Charles

+0

О, и я не говорил об одном, что это только для одного вида. Вы можете просто разделить свои данные по ракурсам по разным видам или использовать кран для работы на основе каждого вида. – Charles

3

Loved решение Чарльза, который прекрасно работает для случая п = 2. Увы, это не распространяется на большие окна. У этой проблемы все еще есть проблема, описанная 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 taskview on time series, особенно раздел о передискретизации. Для нерегулярных временных рядов пакет zoo также предлагает множество других функций, которые могут пригодиться.