0
votes

Puis-je attribuer un résultat de la fonction de vecteur de la colonne de données divisée d'un Tibble?

J'ai quelques données bien rangées, comprenant des séries de longueur identiques de "valeur" ordonnée par "IDX", identifiée par "ID", classée par "type", avec une colonne de résultat vide "Rollagg" marquée sur.

    ## switchable mean/sum function
    mean_sum <- function(x, b = TRUE){
      if (b) 
      {
        mean(x)
      } else {
        sum(x)
      }
    }
    ##

    #dummy data
    df <- tibble(id = rep(1:6, each = 10), idx = rep(1:10, 6), type = rep(c('A', 'B'), each = 10, times = 3), value = runif(60, 1, 5), rollAgg = 0.0)

    #test mean/sum function on single 'id', and assign result to 'rollAgg' column
    d <- df[df$id==2,]
    z <- zoo(d$value, order.by = d$idx)
    par <- d$type[1]
    d$rollAgg <- (rollapply(z, 5, mean_sum, b = (par == 'A'), fill = NA, align = 'right'))

    #prepare split data
    by_id <- split(df, df$id)

    #assign result to pre-assigned matrix
    result <- as_tibble(matrix(data=0.0, nrow = 10, ncol = 6, dimnames=list(NULL,seq(1,6,1))))

    for (i in seq_along(by_id)){
      par <- by_id[[i]]$type[1]
      z <- zoo(by_id[[i]]$value, order.by = by_id[[i]]$idx)
      result[[i]] <- rollapply(z, 5, mean_sum, b = (par == 'A'), fill = NA, align = 'right')
    }

#... which works - columns are alternating mean() and sum():
> head(result, 10)
# A tibble: 10 x 6
   `1`       `2`       `3`       `4`       `5`       `6`      
   <S3: zoo> <S3: zoo> <S3: zoo> <S3: zoo> <S3: zoo> <S3: zoo>
 1       NA        NA        NA        NA        NA        NA 
 2       NA        NA        NA        NA        NA        NA 
 3       NA        NA        NA        NA        NA        NA 
 4       NA        NA        NA        NA        NA        NA 
 5 2.702983  14.35262  2.308507  16.58130  2.808490  14.63715 
 6 2.263146  13.47958  2.026396  14.90904  2.733020  14.75438 
 7 2.757074  15.46849  2.073545  16.27923  2.508627  14.56983 
 8 3.135715  14.84012  2.003807  13.15344  2.834664  14.33360 
 9 3.348647  15.67731  2.377744  14.19039  2.584147  16.21944 
10 3.907222  14.40763  2.520130  14.86086  2.915271  15.48656

    #try to assign result direct to split data, without success...
    for (i in by_id){
      par <- i$type[1]
      z <- zoo(i$value, order.by = i$idx)
      i$rollAgg <- rollapply(z, 5, mean_sum, b = (par == 'A'), fill = NA, align = 'right')
    }

    # finally, not sure how to unsplit() by_id to revert to original df...

r

1 commentaires

tandis que j'ai trouvé une bonne solution pour mon projet et je suis également reconnaissant pour l'approche de @ g-Grothendieck à ajouter à l'Arsenal, je n'ai toujours pas de réponse à la question principale de savoir si les données divisées peuvent être traitées / modifiées et recombinée ...


3 Réponses :


0
votes

À propos de

Je ne sais pas comment malplater ...

une réponse courte avec des données IRIS :) xxx


2 commentaires

Merci - c'est ce que j'ai essayé (je pense ...): résultat2 <- malplit (by_id, f = df $ ID) mais qui génère une erreur: erreur dans . rownamedf <- (x, valeur = valeur): Dupliquer 'Row.Names' ne sont pas autorisés: Messages d'avertissement: 1: La longueur de l'index logique doit être de 1 ou 10, pas 60 2: Réglage des noms de ligne sur un Tibble est obsolète. 3: valeurs non uniques lors de la réglage 'Row.Names': '1', '10', '2', '3', '3', '4', '5', '6', '6', '7', '8', '9' SO DustLIT () semble essayer de définir des noms de ligne ...


(PS: Je ne peux pas faire des pauses en ligne dans des commentaires pour une raison quelconque - désolé)



1
votes

Si votre objectif est d'exécuter RollApply code> sur Valeur code> séparément pour chaque identifiant code> au lieu d'utiliser Split code>. Ave CODE>:

b <- TRUE
rollb <- function(b) {
  function(x) rollapplyr(x, 5, mean_sum, b = b, fill = NA)
}
transform(df, rollAgg = ave(value, id, FUN = rollb(b)))


2 commentaires

merci - il y a la complexité supplémentaire de b être dépendante du "type", c'est-à-dire pas toujours vrai


Vous pouvez remplacer true par une variable. Voir la réponse modifiée.



0
votes

Une solution soignée, basée sur RollMean avec dplyr et Magrittr xxx


0 commentaires