首页 > 解决方案 > 如何停止 slide() 函数将数字向量计算到列表中?

问题描述

我有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)

但是,当我尝试使用 and 计算这个新列时mutate()slide()它会在数据框中返回一个列表,而不是数字变量:

library(dplyr)
library(slider)

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

为什么会发生这种情况,以及如何slide()返回数字变量?

标签: rdplyr

解决方案


似乎默认方法要求list输出。根据?slide

vec_ptype(幻灯片(.x))==列表()

并且描述.ptype

.ptype - [向量(0)/空]

对应于输出类型的原型。

如果默认值为 NULL,则输出类型是通过计算对 .f 的调用结果的公共类型来确定的。

如果提供,每次调用 .f 的结果都将转换为该类型,最终输出将具有该类型。

如果 getOption("vctrs.no_guessing") 为 TRUE,则必须提供 .ptype。这是一种使生产代码需要固定类型的方法。

本质上基于源代码(如下),默认情况下返回 alist并且似乎没有选项可以阻止这种情况,除非我们选择描述的特定方法,即_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并假设.ptypeaslist并且没有选项可以传递该信息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())
}

推荐阅读