首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用的`...first元素出现问题

使用的`...first元素出现问题
EN

Stack Overflow用户
提问于 2021-11-08 14:47:56
回答 1查看 49关注 0票数 0

我有一个向量化的函数,定义如下:

代码语言:javascript
复制
hai_hyperbolic_vec <- function(.x, .scale_type = c("sin","cos","tan","sincos")){

    scale_type = base::as.character(.scale_type)
    term       = .x

    if (scale_type == "sin"){
        ret <- base::sin(term)
    } else if (scale_type == "cos") {
        ret <- base::cos(term)
    } else if (scale_type == "tan") {
        ret <- base::tan(term)
    } else if (scale_type == "sincos") {
        ret <- base::sin(term) * base::cos(term)
    }

    return(ret)

}

这个很好用。

代码语言:javascript
复制
library(tidyverse)

len_out    = 10
by_unit    = "month"
start_date = as.Date("2021-01-01")

data_tbl <- tibble(
    date_col = seq.Date(from = start_date, length.out = len_out, by = by_unit),
    a    = rnorm(len_out),
    b    = runif(len_out)
)

hai_hyperbolic_vec(data_tbl$b, .scale_type = "sin")
> hai_hyperbolic_vec(data_tbl$b, .scale_type = "sin")
 [1] 0.02405150 0.40920185 0.39953987 0.16234068 0.04183186 0.57301045 0.74441929 0.60728533
 [9] 0.69755824 0.46611496

我还有另一个函数可以增强data.frame/tibble

代码语言:javascript
复制
hai_hyperbolic_augment <- function(.data
                                   , .value
                                   , .names = "auto"
                                   , .scale_type = c("sin","cos","tan","sincos")
){

    column_expr <- rlang::enquo(.value)

    if(rlang::quo_is_missing(column_expr)) stop(call. = FALSE, "hyperbolic_augment(.value) is missing.")

    col_nms <- names(tidyselect::eval_select(rlang::enquo(.value), .data))

    make_call <- function(col, scale_type){
        rlang::call2(
            "hai_hyperbolic_vec",
            .x            = rlang::sym(col)
            , .scale_type = .scale_type
            , .ns         = "healthyR.ai"
        )
    }

    grid <- expand.grid(
        col                = col_nms
        , scale_type       = .scale_type
        , stringsAsFactors = FALSE
    )

    calls <- purrr::pmap(.l = list(grid$col, grid$scale_type), make_call)

    if(any(.names == "auto")) {
        newname <- paste0(grid$col, "_", grid$scale_type)
    } else {
        newname <- as.list(.names)
    }

    calls <- purrr::set_names(calls, newname)

    ret <- tibble::as_tibble(dplyr::mutate(.data, !!!calls))

    return(ret)

}

该函数可以工作,但如果我选择了多个.scale_type,即使执行了计算,它也会发出警告消息。我不明白为什么会发生这种情况,因为向量函数是通过purrr应用于列表的。我可以将此警告静默吗?或者有没有更好的方法来编写函数/或使用函数来避免这种情况发生?是否严格要求调用一个scale_type?我更喜欢像我这样调用,因为网格是在增强函数中创建的。

代码语言:javascript
复制
> hai_hyperbolic_augment(.data = data_tbl, .value = c(a,b), .scale_type = c("sin","tan"))
# A tibble: 10 x 7
   date_col         a      b   a_sin  b_sin   a_tan  b_tan
   <date>       <dbl>  <dbl>   <dbl>  <dbl>   <dbl>  <dbl>
 1 2021-01-01 -1.96   0.0241 -0.925  0.0241 -0.925  0.0241
 2 2021-02-01 -1.03   0.422  -0.856  0.409  -0.856  0.409 
 3 2021-03-01  1.55   0.411   1.00   0.400   1.00   0.400 
 4 2021-04-01  0.108  0.163   0.108  0.162   0.108  0.162 
 5 2021-05-01 -0.627  0.0418 -0.587  0.0418 -0.587  0.0418
 6 2021-06-01 -0.556  0.610  -0.528  0.573  -0.528  0.573 
 7 2021-07-01 -0.0544 0.840  -0.0544 0.744  -0.0544 0.744 
 8 2021-08-01 -0.714  0.653  -0.655  0.607  -0.655  0.607 
 9 2021-09-01 -0.646  0.772  -0.602  0.698  -0.602  0.698 
10 2021-10-01 -1.06   0.485  -0.873  0.466  -0.873  0.466 
Warning messages:
1: Problem with `mutate()` column `a_sin`.
i `a_sin = healthyR.ai::hai_hyperbolic_vec(...)`.
i the condition has length > 1 and only the first element will be used 
2: Problem with `mutate()` column `b_sin`.
i `b_sin = healthyR.ai::hai_hyperbolic_vec(...)`.
i the condition has length > 1 and only the first element will be used 
3: Problem with `mutate()` column `a_tan`.
i `a_tan = healthyR.ai::hai_hyperbolic_vec(...)`.
i the condition has length > 1 and only the first element will be used 
4: Problem with `mutate()` column `b_tan`.
i `b_tan = healthyR.ai::hai_hyperbolic_vec(...)`.
i the condition has length > 1 and only the first element will be used
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-08 15:32:23

出现问题的原因是您向hai_hyperbolic_vec.scale_type参数传递了两个参数。

如果您进入调试器并查看由calls <- purrr::set_names(calls, newname)行创建的calls对象,您将看到:

代码语言:javascript
复制
calls
#> $a_sin
healthyR.ai::hai_hyperbolic_vec(.x = a, .scale_type = c("sin", "tan"))
#> 
#> $b_sin
#> healthyR.ai::hai_hyperbolic_vec(.x = b, .scale_type = c("sin", "tan"))
#> 
#> $a_tan
#> healthyR.ai::hai_hyperbolic_vec(.x = a, .scale_type = c("sin", "tan"))
#> 
#> $b_tan
#> healthyR.ai::hai_hyperbolic_vec(.x = b, .scale_type = c("sin", "tan"))

但是在hai_hyperbolic_vec函数中,我们看到一行if (scale_type == "sin")。因此,对于上面在call对象中显示的每个调用,您都会将一个长度为2的向量传递给这个逻辑测试。它将只检查向量的第一个成员,并发出警告,说明它已经这样做了。

您将注意到您的输出实际上也是错误的- a_tanb_tan列与a_sinb_sin列相同,因为逻辑意味着只计算sin

我认为这是由于函数make_call中的一个拼写错误(添加了一个句点)造成的,在这个函数中,您意外地使用了.scale_type,而实际上您应该使用scale_type

代码语言:javascript
复制
    make_call <- function(col, scale_type){
        rlang::call2(
            "hai_hyperbolic_vec",
            .x            = rlang::sym(col)
            , .scale_type = .scale_type # <- here is the problem
            , .ns         = "healthyR.ai"
        )
    }

应该是

代码语言:javascript
复制
    make_call <- function(col, scale_type){
        rlang::call2(
            "hai_hyperbolic_vec",
            .x            = rlang::sym(col)
            , .scale_type = scale_type
            , .ns         = "healthyR.ai"
        )
    }

如果进行此更改,则不会收到任何警告,也不会得到正确的结果:

代码语言:javascript
复制
hai_hyperbolic_augment(.data = data_tbl, .value = c(a,b), .scale_type = c("sin","tan"))
#> # A tibble: 10 x 7
#>    date_col         a     b   a_sin b_sin   a_tan b_tan
#>    <date>       <dbl> <dbl>   <dbl> <dbl>   <dbl> <dbl>
#>  1 2021-01-01 -1.01   0.977 -0.849  0.829 -1.61   1.48 
#>  2 2021-02-01  0.424  0.719  0.411  0.658  0.451  0.875
#>  3 2021-03-01 -0.133  0.338 -0.132  0.332 -0.134  0.352
#>  4 2021-04-01  0.259  0.238  0.256  0.235  0.265  0.242
#>  5 2021-05-01  0.631  0.110  0.590  0.109  0.731  0.110
#>  6 2021-06-01 -0.0500 0.995 -0.0500 0.839 -0.0500 1.54 
#>  7 2021-07-01  0.302  0.569  0.298  0.539  0.312  0.639
#>  8 2021-08-01 -0.681  0.901 -0.629  0.784 -0.810  1.26 
#>  9 2021-09-01 -0.296  0.374 -0.292  0.365 -0.305  0.393
#> 10 2021-10-01 -0.384  0.506 -0.374  0.484 -0.404  0.554
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69885415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档