【问题标题】:How do I write function to convert a character vector to minutes?如何编写函数将字符向量转换为分钟?
【发布时间】:2021-12-24 16:08:56
【问题描述】:

我想编写一个函数,将“time_spent”列中的字符向量转换为分钟的数值向量。

#Import libraries
library(tidyr)
library(dplyr)
library(lubridate)

#Create dataframe
df <- data.frame(country = c("Russia", "China", "USA"),
                 time_spent = c("0:10", "1:20", "2:36"))

#Convert "time_spent" from factor to character
df$time_spent <- lapply(df$time_spent, as.character)

我可以用下面的代码做到这一点,但我想学习如何把它写成一个函数。

df %>% 
  mutate(minutes = paste(time_spent, "00", sep = ":"),
         minutes = hms(minutes),
         minutes = hour(minutes)*60 + minute(minutes))

我知道我已经破坏了这个函数及其应用程序,但我不知道如何让它工作。

#Function to convert "time_spent" vector into minutes
convert_to_minutes <- function(x) {
  df$x = paste(x, "00", sep = ":") %>% 
  df$x = hms(x) %>% 
  df$x = hour(x)*60 + minute(x)
  }

#Apply function
df %>% 
  convert_to_minutes(df$time_spent)

相关问题2

如何使用map 将我的convert_to_minutes 函数应用于多个time_spent 向量,如下面的数据帧中所示?

df2 <- data.frame(country = c("Russia", "China", "USA"),
                 time_spent = c("0:10", "1:20", "2:36"),
                 time_spent2 = c("0:15", "0:12", "1:47"),
                 time_spent3 = c("0:25", "3:45", "0:18"))

【问题讨论】:

  • 所以"1:20" 是"HH:MM"?
  • 是的,没错。

标签: r function


【解决方案1】:

您的函数中几乎没有拼写错误和语法错误。你可以使用 -

library(lubridate)
library(dplyr)

convert_to_minutes <- function(x) {
  x = paste(x, "00", sep = ":") 
  x = lubridate::hms(x) 
  x = x@hour *60 + x@minute
  x
}

convert_to_minutes(df$time_spent)
#[1]  10  80 156

要将其应用于多个列,您可以在 tidyverse 中使用 across(或在 base R 中使用 lapply)。

df2 %>%
  mutate(across(contains('time_spent'), convert_to_minutes))

#  country time_spent time_spent2 time_spent3
#1  Russia         10          15          25
#2   China         80          12         225
#3     USA        156         107          18

【讨论】:

  • 谢谢。这个帖子里有很多很好的答案,但我发现这个是最直观的。
【解决方案2】:

转换为分钟的函数,仅在基数 R 中,可能如下。

convert_to_minutes <- function(x) {
  f <- function(x) as.vector(as.integer(x) %*% c(60, 1))
  y <- strsplit(as.character(x), ":")
  sapply(y, f)
}

y <- c("0:10", "1:20", "2:36")
convert_to_minutes(y)
#[1]  10  80 156

转换一个data.frame列,用dplyr函数mutate。

library(dplyr)

df %>%
  mutate(minutes = convert_to_minutes(time_spent))
#  country time_spent minutes
#1  Russia       0:10      10
#2   China       1:20      80
#3     USA       2:36     156

要转换多列,请使用mutate(across(.))。

df2 %>%
  mutate(across(starts_with("time"), convert_to_minutes, .names = "minutes_{col}"))
#  country time_spent time_spent2 time_spent3 minutes_time_spent minutes_time_spent2 minutes_time_spent3
#1  Russia       0:10        0:15        0:25                 10                  15                  25
#2   China       1:20        0:12        3:45                 80                  12                 225
#3     USA       2:36        1:47        0:18                156                 107                  18

【讨论】:

  • @MerijnvanTilborg 给我一点时间,我会回答第二个请求。
【解决方案3】:

由于您已经在使用 lubridate,因此您可以更有效地使用它。除了使用lubridate::hms,它还支持lubridate:hm。另一个方便的功能是lubridate::as.duration,它允许您格式化任何度量,在您的情况下是分钟。然后只需将持续时间转换为数字即可。

x <- c("0:10", "1:20", "2:36")
as.numeric(as.duration(hm(x)), "minutes")
# [1]  10  80 156

转换 df2 的完整答案

df2 <- data.frame(country = c("Russia", "China", "USA"),
                 time_spent = c("0:10", "1:20", "2:36"),
                 time_spent2 = c("0:15", "0:12", "1:47"),
                 time_spent3 = c("0:25", "3:45", "0:18"))

library(lubridate)
library(data.table)
setDT(df2)

cols <- 2:length(names(df2))

df2[, (cols) := lapply(.SD, function(x) as.numeric(as.duration(hm(x)), "minutes")), .SDcols = cols]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2020-01-28
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 2019-10-26
    相关资源
    最近更新 更多