#r #dplyr
#r #dplyr
Вопрос:
У меня есть data.frame
один столбец:
Price <- c(1, 2, 5, 3, 1, 4, 7, 10, 6)
df <- data.frame(Price)
Я хочу вычислить максимальное значение каждого из семи чисел, в результате чего:
df$MaxPrice <- c(1, 2, 5, 5, 5, 5, 7, 10, 10)
Однако, когда я пытаюсь вычислить этот новый столбец с mutate()
помощью and slide()
, он возвращает мне список внутри фрейма данных вместо числовой переменной:
library(dplyr)
library(slider)
df <- df %>%
mutate(MaxPrice = slide(Price, max, .before = 7, .after = 0, .complete = F))
Почему это происходит и как заставить slide()
возвращать числовую переменную?
Ответ №1:
Похоже, что метод по умолчанию вызывает list
вывод. Согласно ?slide
vec_ptype(slide(.x)) == list()
и описание для .ptype
этого
.ptype — [вектор(0) / NULL]
Прототип, соответствующий типу выходного сигнала.
Если значение по умолчанию равно NULL, то тип вывода определяется путем вычисления общего типа для результатов вызовов .f.
Если указано, результат каждого вызова .f будет приведен к этому типу, и конечный результат будет иметь этот тип.
Если getOption(«vctrs.no_guessing») имеет значение TRUE, должен быть указан .ptype . Это способ заставить производственный код требовать фиксированных типов.
По сути, основываясь на исходном коде (ниже), он по умолчанию возвращает a list
, и, похоже, нет возможности предотвратить это, если мы не выберем конкретные описанные методы, т.е. _vec
или _dbl
Либо мы могли бы 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
Или используйте метод, зависящий от типа, т.е. 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
Если мы проверяем исходный код slide
, он вызывает slide_impl
и предполагает, что .ptype
as list
и нет возможности передать эту информацию slide
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)
}
Теперь сравните это с _dbl
методом
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. Спасибо, это сработало. Однако я могу принять его только через 10 минут. Вы знаете, почему это произошло именно так? Я имею в виду, slide() не всегда возвращает списки, не так ли?
2. @Escurisse Это связано с исходным кодом. Я обновил сообщение.
3. Спасибо за ваш подробный ответ!
Ответ №2:
Вы можете просто использовать cummax
функцию в базе R:
Price <- c(1, 2, 5, 3, 1, 4, 7, 10, 6)
cummax(Price)
[1] 1 2 5 5 5 5 7 10 10
Для многовекторного случая. Загрузите вектор данных в матрицу и примените cummax к столбцам. Генерирует матрицу векторов cummax для последующей обработки:
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
Комментарии:
1. Хорошо, спасибо за ваш ответ. Это сработало для тех выборочных данных, которые я предоставил. Однако, поскольку я хочу «вычислить максимальное значение для каждых семи чисел», тогда это решение не будет расширяемо до большего фрейма данных, верно?
2.
cummax
Функция может быть расширена до любой длины. Что еще ты пытаешься сделать?3. Извините, возможно, я недостаточно ясно выразился. Я пытался получить максимальное значение цены для каждой группы из семи последовательных значений. Я полагаю , что существует также действительное и хорошее решение этой проблемы с
cummax
помощью . Это также может быть полезно для меня и других пользователей, чтобы узнать об этом. Но мой вопрос касался конкретно поведенияslide()
функции при решении моей проблемы.4. ОК. Я присоединяюсь к пословице Эйнштейна при написании кода: «Все должно быть сделано как можно проще, но не проще» Пример Multi cummax обновленный ответ.
5. Вы, без сомнения, правы. Спасибо за ваше время и ответ ( 1). Будет ли этот код вычислять максимум для каждой группы из 7 значений, несмотря на столбец, к которому я его применяю?