Wie kann ich verhindern, dass die Funktion slide () einen numerischen Vektor in eine Liste berechnet?

Nov 25 2020

Ich habe eine data.framevon einer Spalte:

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

Ich möchte den Maximalwert von jeweils sieben Zahlen berechnen, was zu Folgendem führt:

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

Wenn ich jedoch versuche, diese neue Spalte mit mutate()und zu berechnen slide(), wird anstelle einer numerischen Variablen eine Liste im Datenrahmen zurückgegeben:

library(dplyr)
library(slider)

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

Warum passiert das und wie kann man slide()eine numerische Variable zurückgeben?

Antworten

3 akrun Nov 25 2020 at 20:18

Es scheint, dass die Standardmethode die listAusgabe aufruft . Gemäß?slide

vec_ptype (slide (.x)) == list ()

und die Beschreibung für .ptypeist

.ptype - [Vektor (0) / NULL]

Ein Prototyp, der dem Typ der Ausgabe entspricht.

Wenn der Standardwert NULL ist, wird der Ausgabetyp bestimmt, indem der gemeinsame Typ für die Ergebnisse der Aufrufe von .f berechnet wird.

Wenn angegeben, wird das Ergebnis jedes Aufrufs von .f in diesen Typ umgewandelt, und die endgültige Ausgabe hat diesen Typ.

Wenn getOption ("vctrs.no_guessing") TRUE ist, muss der .ptype angegeben werden. Auf diese Weise kann der Produktionscode feste Typen erfordern.

Im Wesentlichen basierend auf dem Quellcode (unten) wird standardmäßig a zurückgegeben, listund es scheint keine Option zu geben, dies zu verhindern, es sei denn, wir entscheiden uns für bestimmte beschriebene Methoden, dh _vecoder_dbl

Entweder wir könnten 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

Oder verwenden Sie die typspezifische Methode, dh 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

Wenn wir den Quellcode überprüfen slide, ruft er , slide_implund es wird davon ausgegangen , dass .ptypeals listund es gibt keine Möglichkeit , dass Informationen passieren inslide

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

Vergleichen Sie das nun mit der _dblMethode

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

Sie können einfach die cummaxFunktion in Basis R verwenden:

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

Für Multi-Vektor-Fall. Laden Sie den Datenvektor in eine Matrix und wenden Sie Cummax auf die Spalten an. Erzeugt eine Matrix von Cummax-Vektoren zur weiteren Behandlung:

    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