Comment empêcher la fonction slide () de calculer un vecteur numérique dans une liste?

Nov 25 2020

J'ai un data.framed'une colonne:

Price <- c(1, 2, 5, 3, 1, 4, 7, 10, 6)
df <- data.frame(Price)

Je veux calculer la valeur maximale de chaque sept nombres, ce qui donne:

df$MaxPrice <- c(1, 2, 5, 5, 5, 5, 7, 10, 10)

Cependant, lorsque j'essaye de calculer cette nouvelle colonne avec mutate()et slide(), cela me renvoie une liste à l'intérieur du dataframe, au lieu d'une variable numérique:

library(dplyr)
library(slider)

df <- df %>% 
  mutate(MaxPrice = slide(Price, max, .before = 7, .after = 0, .complete = F))

Pourquoi cela se produit-il et comment faire slide()renvoyer une variable numérique?

Réponses

3 akrun Nov 25 2020 at 20:18

Il semble que la méthode par défaut appelle la listsortie. Selon?slide

vec_ptype (diapositive (.x)) == liste ()

et la description de .ptypeest

.ptype - [vecteur (0) / NULL]

Un prototype correspondant au type de sortie.

Si NULL, la valeur par défaut, le type de sortie est déterminé en calculant le type commun à travers les résultats des appels à .f.

S'il est fourni, le résultat de chaque appel à .f sera converti en ce type et la sortie finale aura ce type.

Si getOption ("vctrs.no_guessing") est TRUE, le .ptype doit être fourni. C'est un moyen de faire en sorte que le code de production demande des types fixes.

Essentiellement basé sur le code source (ci-dessous), il renvoie par défaut a listet il ne semble y avoir aucune option pour empêcher cela à moins que nous n'options pour des méthodes spécifiques décrites, c'est-à-dire _vecou_dbl

Soit nous pourrions flatten

library(dplyr)
library(slider)
library(purrr)
out <- df %>% 
    mutate(MaxPrice = slide(Price, max, .before = 7, .after = 0,
       .complete = FALSE) %>% flatten_dbl) 

str(out)
#'data.frame':  9 obs. of  2 variables:
# $ Price : num 1 2 5 3 1 4 7 10 6 # $ MaxPrice: num  1 2 5 5 5 5 7 10 10

Ou utilisez la méthode spécifique au type, c'est-à-dire slide_dbl

out <- df %>% 
    mutate(MaxPrice = slide_dbl(Price, max, .before = 7, .after = 0,
       .complete = FALSE) )

str(out)
#'data.frame':  9 obs. of  2 variables:
# $ Price : num 1 2 5 3 1 4 7 10 6 # $ MaxPrice: num  1 2 5 5 5 5 7 10 10

Si nous vérifions le code source de slide, il appelle slide_implet suppose qu'au .ptypefur listet à mesure , il n'y a pas d'option pour transmettre ces informationsslide

slide
function (.x, .f, ..., .before = 0L, .after = 0L, .step = 1L, 
    .complete = FALSE) 
{
    slide_impl(.x, .f, ..., .before = .before, .after = .after, 
        .step = .step, .complete = .complete, .ptype = list(), 
        .constrain = FALSE, .atomic = FALSE)
}

Maintenant, comparez cela avec la _dblméthode

slide_dbl
function (.x, .f, ..., .before = 0L, .after = 0L, .step = 1L, 
    .complete = FALSE) 
{
    slide_vec_direct(.x, .f, ..., .before = .before, .after = .after, 
        .step = .step, .complete = .complete, .ptype = double())
}
1 SteveM Nov 25 2020 at 21:01

Vous pouvez simplement utiliser la cummaxfonction en base R:

Price <- c(1, 2, 5, 3, 1, 4, 7, 10, 6)
cummax(Price)
[1]  1  2  5  5  5  5  7 10 10

Pour cas multi-vecteurs. Chargez le vecteur de données dans une matrice et appliquez cummax aux colonnes. Génère une matrice de vecteurs cummax pour le traitement de suivi:

    Prices <- sample(1:10, 70, replace = TRUE) # dummy data
     [1] 10  1  1  9  9  6  6  9  7  3  6  4 10  4  8  6  6  9  2  1  6  4  7 10  1  6  5  2  7  7  4  6  7  7  7
    [36]  2  8  5  4  8  4  7  7  1  7  5  9  6  7  3 10  5 10  1  2  5  1  1  8  5  8  8  6  8  6  8 10  4  8  8
    matPrices <- matrix(Prices, ncol = 10)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]   10    9    8    4    7    2    7    3    1     8
[2,]    1    7    6    7    7    8    1   10    1     6
[3,]    1    3    6   10    4    5    7    5    8     8
[4,]    9    6    9    1    6    4    5   10    5    10
[5,]    9    4    2    6    7    8    9    1    8     4
[6,]    6   10    1    5    7    4    6    2    8     8
[7,]    6    4    6    2    7    7    7    5    6     8
    matcummax <- apply(matPrices, 2, cummax)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]   10    9    8    4    7    2    7    3    1     8
[2,]   10    9    8    7    7    8    7   10    1     8
[3,]   10    9    8   10    7    8    7   10    8     8
[4,]   10    9    9   10    7    8    7   10    8    10
[5,]   10    9    9   10    7    8    9   10    8    10
[6,]   10   10    9   10    7    8    9   10    8    10
[7,]   10   10    9   10    7    8    9   10    8    10