Comment échantillonne n valeurs au plus proche de la valeur aléatoire y lorsque les données ne sont pas continues?

StackOverflow https://stackoverflow.com/questions/3950877

Question

J'ai un ensemble de données qui comprend une liste des espèces, leur nombre et le nombre de jours du moment où l'enquête a commencé. Depuis plusieurs jours ne sont pas échantillonnés, le jour n'est pas continue. Ainsi, par exemple, il pourrait y avoir des oiseaux comptés le jour 5,6,9,10,15,34,39 et ainsi de suite. Je mis la première date à être jour 0.

Exemple de données:

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
..................

Je dois bootstrap ces données et obtenir un ensemble de données résultant où je précise quand commencer, quel intervalle de procéder et le nombre de points à échantillon.

Exemple: Disons que je prends au hasard 5 jours comme le jour de départ, l'intervalle 30, et le nombre de lignes à échantillon 2. Cela signifie que je vais commencer à 5, ajouter 30 à, et look pour 2 rangées autour de 35 jours (mais pas le jour lui-même 35). Dans ce cas, je vais saisir les deux lignes où le jour est de 34 et 39.

Ensuite, j'ajouter 30 à 35 et de chercher deux points environ 65. Rincez, répétez jusqu'à ce que j'arrive à la fin de l'ensemble de données.

J'ai écrit cette fonction pour faire l'échantillonnage, mais il a des défauts (voir ci-dessous):

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)
 } 

Deux questions dont j'ai besoin d'aide avec:

  1. Alors que ma fonction ne retourne le nombre désiré de points, il n'est pas centrée autour de ma valeur de recherche. Est logique parce que je reçois plus, je reçois plus de points et quand je trie les et choisissez premier n, ils ont tendance à ne pas être les valeurs basses.

  2. Deuxièmement, comment puis-je obtenir les lignes réelles sur? Pour l'instant j'ai une autre fonction pour localiser ces lignes à l'aide which, puis rbind « ing ces lignes ensemble. On dirait qu'il devrait y avoir une meilleure façon.

merci!

Était-ce utile?

La solution

Que diriez-vous quelque chose comme ce qui suit:

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]

Pour obtenir les lignes de votre data.frame sous-ensemble de juste:

rows = data[pos, ]

Ceci est peut-être un peu plus propre que le unlist / lapply / combo suivants:

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

Notez également que si vous voulez une fenêtre plus grande (par exemple, dire 4), juste une question de revenir en arrière un peu:

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

Autres conseils

Nous avons adoré la solution de Charles, qui fonctionne parfaitement pour le cas n = 2. Hélas, ce n'est pas de fenêtres plus grandes prorogeable. Il a encore le problème décrit par OP: avec des fenêtres plus grandes, la sélection n'est pas centrée autour de la valeur de recherche. Compte tenu de n est même, je suis venu avec la solution suivante, fortement basée sur idée Charles.

La fonction contrôle les frontières. s'il y a 100 jours, et le prochain point médian est de dire le dernier jour, une fenêtre de 4 signifierait que vous sélectionnez l'indice 101, ce qui donne NA. Cette fonction décale la fenêtre pour tous les indices sélectionnés se trouvent dans les données d'origine. Cela a aussi l'effet secondaire en fonction des valeurs de départ (st), longueur (l) et la fenêtre des valeurs (n) du début et la fin ont une plus grande chance d'être sélectionné deux fois. Les longueurs doivent toujours être au moins la taille de la fenêtre deux fois.

La sortie de la fonction sont les indices de l'échantillon de bootstrap. Il peut être utilisé comme la variable pos de Charles sur les vecteurs et dataframes.

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)
}

Ensuite

>   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
> 

edit: en ce qui concerne bootstrapping pour les séries temporelles, vous devez passer par le CRAN taskview sur séries temporelles , en particulier la section sur rééchantillonnage. Pour les séries de temps irréguliers, le paquet zoo offre également tout à fait d'autres fonctionnalités qui peuvent être utiles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top