R 函数必须在 tidyverse 的 mutate 函数中使用什么参数?

Ste*_*ger 3 r tidyverse mutate

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

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

  • “5”(表示 5 分钟)
  • “XX分钟”(意思是xx分钟)
  • “X 标准”(意味着 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)
}
Run Code Online (Sandbox Code Playgroud)

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

convert_ZA_time("2 Std. 50 min")
# prints [1] 170
Run Code Online (Sandbox Code Playgroud)

但是当我尝试在 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
Run Code Online (Sandbox Code Playgroud)

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

PS,据我所知:mutate 获取每个“datestr”并将其放入函数“convert_ZA_time”中。但显然 mutate 将向量放入函数中?

谢谢你的帮助!

jay*_*.sf 6

你的函数Vectorize还没有完成。

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
Run Code Online (Sandbox Code Playgroud)

使固定:

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 
Run Code Online (Sandbox Code Playgroud)

解释

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

fun <- function(x) if (x >= 0) "pos" else "neg"
Run Code Online (Sandbox Code Playgroud)

当应用于v长度大于 1的ector 时,它仅评估带有警告的第一个元素。

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"
Run Code Online (Sandbox Code Playgroud)

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

funv <- Vectorize(fun)
funv(v)
# [1] "neg" "neg" "pos" "pos" "pos"
Run Code Online (Sandbox Code Playgroud)