gpt4 book ai didi

r - Tidyeval in own functions in own functions inside own functions with the pipe 管道

转载 作者:行者123 更新时间:2023-12-01 08:01:31 31 4
gpt4 key购买 nike

所以我正在尝试制作一个包(我没有在下面包含我的 roxygen2 header ):

我有这个功能:

date_from_text <- function(df, x){
x <- rlang::enquo(x)
name <- rlang::quo_name(x)

df %>%
dplyr::mutate(!!name := lubridate::ymd_hms(!!x))
}

当日期时间列具有正确的类时,我将使用它来提取所有组件。

date_columns <- function(df, x){

x <- rlang::enquo(x)

df %>%
dplyr::mutate(year=lubridate::year(!!x),
ydag=lubridate::yday(!!x),
weekday=lubridate::wday(!!x, label=FALSE),
hour = lubridate::hour(!!x),
hour_min= hms::as.hms(lubridate::force_tz(!!x)),
week_num = lubridate::week(!!x),
month = lubridate::month(!!x),
date = lubridate::date(!!x))
}

我不想将 date_from_text 函数包含在 NAMESPACE 中,我想以某种方式将它包含在 date_columns 函数中。比如检查时间戳是否有正确的类,如果没有则更改类......然后创建所有日期时间组件。

我不知道如何在另一个函数中调用第一个函数。

测试数据:

df <- structure(list(time = c("2018-01-30 20:08:18", "2018-02-01 21:01:25", 
"2018-01-31 23:25:12", "2018-01-28 23:45:34", "2018-01-31 12:00:55",
"2018-02-04 09:15:31", "2018-01-27 21:08:02", "2018-02-08 01:50:31",
"2018-02-01 03:15:43", "2018-02-04 01:04:52"), type = c("A",
"D", "B", "B", "B", "D", "C", "C", "C", "A")), .Names = c("time",
"type"), row.names = c(NA, -10L), class = c("tbl_df", "tbl",
"data.frame"))

更新:所以我现在将 date_from_text 包含在 date_columns

date_columns <- function(df, x){
x <- rlang::enquo(x)

out <- df %>%
date_from_text(!!x) %>%
dplyr::mutate(year=lubridate::year(!!x),
ydag=lubridate::yday(!!x),
weekday=lubridate::wday(!!x, label=FALSE),
hour = lubridate::hour(!!x),
hour_min= hms::as.hms(lubridate::force_tz(!!x)),
week_num = lubridate::week(!!x),
month = lubridate::month(!!x),
date = lubridate::date(!!x))
out

}

所以我不明白为什么我必须在 date_columns 中再次使用 !!x?它已经包含在 date_from_text 中。我正在调用函数而不是创建它...

最佳答案

正如在评论和聊天中所讨论的那样,问题既不是关于包开发和命名空间,也不是关于管道。问题是如何使用 在可能嵌套的包装函数中。

答案是用户传递给函数的表达式需要是 quoted and unquoted , 就像在 date_from_text() 中一样下面通过 enquo(x)!!x .

date_from_text <- function(df, x) {
x <- rlang::enquo(x) # quote via enquo()
name <- rlang::quo_name(x)
dplyr::mutate(df, !!name := lubridate::ymd_hms(!!x)) # unquote via !!
}

然后,可以将表达式以“交互”模式传递给此类函数,就像 dplyr 函数一样:

date_from_text(df, time)
select(df, time)

请记住,函数内的函数不采用表达式,而是带引号和不带引号的表达式,就像在 mutate() 中一样用 enquo(x) 打电话和 !!x以上。

这意味着,在 date_from_text() 中下面,两个电话date_from_text()mutate()需要领取!!x .

date_columns <- function(df, x) {
x <- rlang::enquo(x)

out <- date_from_text(df, !!x)
out <- dplyr::mutate(out, year = lubridate::year(!!x))
return(out)
}

除此之外,在包开发中,您可以使用所有函数,无论它们是exported。或不(就像我在 date_from_text() 中对 date_columns() 所做的那样)。导出的函数需要记录在案,安装后可以通过library(pkg)使用或 pkg::fun() , 而未导出的功能只能在通过 pkg:::fun() 安装后使用.

我修改了@David 的函数以专注于相关部分

关于r - Tidyeval in own functions in own functions inside own functions with the pipe 管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55899506/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com