Jak zatrzymać funkcję slide () przed obliczeniem wektora numerycznego na listę?
Mam data.frame
jedną kolumnę:
Price <- c(1, 2, 5, 3, 1, 4, 7, 10, 6)
df <- data.frame(Price)
Chcę obliczyć maksymalną wartość każdego z siedmiu liczb, w wyniku czego:
df$MaxPrice <- c(1, 2, 5, 5, 5, 5, 7, 10, 10)
Jednak gdy próbuję obliczyć tę nową kolumnę za pomocą mutate()
i slide()
, zwraca mi listę wewnątrz ramki danych, zamiast zmiennej numerycznej:
library(dplyr)
library(slider)
df <- df %>%
mutate(MaxPrice = slide(Price, max, .before = 7, .after = 0, .complete = F))
Dlaczego tak się dzieje i jak sprawić, by slide()
zwracała zmienną numeryczną?
Odpowiedzi
Wygląda na to, że domyślna metoda wywołuje dane list
wyjściowe. Według?slide
vec_ptype (slajd (.x)) == lista ()
a opis .ptype
to
.ptype - [wektor (0) / NULL]
Prototyp odpowiadający typowi wyjścia.
Jeśli NULL, domyślny typ danych wyjściowych jest określany przez obliczanie wspólnego typu w wynikach wywołań .f.
Jeśli zostanie podana, wynik każdego wywołania .f zostanie rzutowany na ten typ, a końcowe wyjście będzie miało ten typ.
Jeśli getOption ("vctrs.no_guessing") ma wartość TRUE, należy podać .ptype. Jest to sposób, aby kod produkcyjny wymagał stałych typów.
Zasadniczo, w oparciu o kod źródłowy (poniżej), domyślnie zwraca a list
i wydaje się, że nie ma opcji, aby temu zapobiec, chyba że zdecydujemy się na określone metody opisane, tj. _vec
Lub_dbl
Albo moglibyśmy 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
Lub użyj metody specyficznej dla typu, tj 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
Jeśli sprawdzimy kod źródłowy programu slide
, wywołuje slide_impl
i zakłada, że .ptype
as list
i nie ma opcji przekazania tych informacjislide
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)
}
Teraz porównaj to z _dbl
metodą
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())
}
Możesz po prostu użyć cummax
funkcji w bazie R:
Price <- c(1, 2, 5, 3, 1, 4, 7, 10, 6)
cummax(Price)
[1] 1 2 5 5 5 5 7 10 10
W przypadku wielu wektorów. Załaduj wektor danych do macierzy i zastosuj cummax do kolumn. Generuje macierz wektorów cummax do dalszego leczenia:
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