【问题标题】:What parameter must an R function have to use it within the mutate function from tidyverse?R 函数必须在 tidyverse 的 mutate 函数中使用什么参数?
【发布时间】:2021-01-21 06:43:28
【问题描述】:

A 有一个带有代表小时和分钟的字符串的列的 tibble。 我想整理该列并将元素转换为仅代表分钟的整数。

这些字符串可以是以下形式之一:

  • “5”(表示 5 分钟)
  • “XX min”(表示 xx 分钟)
  • “X Std”(表示 x 小时)
  • “X Std. YY min”(表示 x 小时和 yy 分钟)

我写了一个函数把这些字符串转换成分钟。

  • “5”应该变成 5。
  • “45 分钟”应变为 45。
  • “2 标准”应变为 120。
  • “1 Std. 30 min”应该变成 90。

这是函数的样子:

convert_ZA_time <- function(string) {
    if (nchar(string) == 1) {
      result <- as.integer(string)
    }
    else if (endsWith(string, " Std")) {
      result <- as.integer(substring(string, 1, 1)) * 60
    }
    else if (endsWith(string, " min") && nchar(string) == 6) {
      result <- as.integer(substring(string, 1, 2))
    }
    else if (endsWith(string, " min") && nchar(string) > 6) {
      hour <- as.integer(gsub(" Std.*", "", string, perl = TRUE))
      minute_plus <- gsub("^\\d+ Std. ", "", string, perl = TRUE)
      minute <- as.integer(gsub(" min$", "", minute_plus))
      result <- hour * 60 + minute
    }
    else {result <- NA}
    return(result)
}

用字符串测试它工作得很好:

convert_ZA_time("2 Std. 50 min")
# prints [1] 170

但是当我尝试在 tidyverse mutate 函数中使用此函数时,我收到以下错误:

df <- tibble(datestr = c("5", "45 min", "1 Std", "2 Std. 30 min"))
df2 <- df %>% mutate(minutes = convert_ZA_time(datestr))
# throws error: the condition has length > 1 and only the first element will be used

如何更改我的函数才能在 mutate 中正确使用它?

附:据我了解:mutate 获取每个“datestr”并将其放入函数“convert_ZA_time”中。但显然 mutate 将向量放入函数中?

感谢您的帮助!

【问题讨论】:

    标签: r tidyverse dplyr


    【解决方案1】:

    你的函数还不是Vectorized。

    convert_ZA_time(c("2 Std. 50 min", "3 Std. 50 min"))
    # [1] 170 230
    # Warning messages:
    # 1: In if (nchar(string) == 1) { :
    #   the condition has length > 1 and only the first element will be used
    # 2: In if (endsWith(string, " Std")) { :
    #   the condition has length > 1 and only the first element will be used
    

    修复:

    convert_ZA_timev <- Vectorize(convert_ZA_time)
          
    convert_ZA_timev(c("2 Std. 50 min", "3 Std. 50 min"))
    # 2 Std. 50 min 3 Std. 50 min 
    #           170           230 
    

    说明

    您的函数中有一个 if / else 结构,如下所示:

    fun <- function(x) if (x >= 0) "pos" else "neg"
    

    当应用于长度大于 1 的 vector 时,它只计算第一个元素并发出警告。

    v <- -2:2
    
    fun(v)
    # [1] "neg"
    # Warning message:
    #   In if (x >= 0) "pos" else "neg" :
    #   the condition has length > 1 and only the first element will be used
    
    fun(v[1])
    # [1] "neg"
    

    向量化使函数能够处理向量。

    funv <- Vectorize(fun)
    funv(v)
    # [1] "neg" "neg" "pos" "pos" "pos"
    

    【讨论】:

    • 非常感谢您的帮助 - 它成功了!应该明确地阅读“?矢量化”;-)
    猜你喜欢
    • 1970-01-01
    • 2020-12-13
    • 2021-02-09
    • 2019-11-05
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 2020-04-16
    相关资源
    最近更新 更多