【问题标题】:In R, how can I parse variables containing "# min" and convert those variables to seconds?在 R 中,如何解析包含“# min”的变量并将这些变量转换为秒?
【发布时间】:2019-11-12 02:51:48
【问题描述】:

我在 tidyverse 工作,我有一个四列 tibble,如下所示:

+-------------------+--------------------+--------------------+-------------+
| application <chr> |      start<chr>    |       end<chr>     |  usage<chr> |
+-------------------+--------------------+--------------------+-------------+
| reddit is fun     | 01-Mar-19 17:37:26 | 01-Mar-19 17:37:36 | 10 sec      |
| Maps              | 01-Mar-19 17:37:38 | 01-Mar-19 17:41:1  | 3 min       |
| Clock             | 01-Mar-19 17:41:10 | 01-Mar-19 17:41:21 | 11 sec      |
+-------------------+--------------------+--------------------+-------------+

我的意图是将使用列中以分钟为单位列出的任何值转换为秒。我可以在 excel 中做到这一点,但我宁愿将 excel 排除在外!

我的想法是我可能需要使用提取函数,对“# min”值使用正则表达式,将“#”和“min”分开,转换为秒,然后合并两列,现在都在几秒钟内,粘贴。

我在正确的轨道上吗?谢谢!

【问题讨论】:

  • 嗨,欢迎来到 SO!您能否以可重复的格式提供您的表格,也许使用dput?见how to make a reproducible example
  • 此外,使用startend 列来获取使用时间而不是解析usage 列可能更有意义,因为这将舍入以分钟为单位的所有值。
  • 这里是 dput 输出结构(list(application = c("Clock", "reddit is fun", "reddit is fun", "Clock"), start = c("01-Mar -19 7:30:03”、“01-Mar-19 7:30:11”、“01-Mar-19 7:35:01”、“01-Mar-19 7:35:03”),结束= c("01-Mar-19 7:30:11", "01-Mar-19 7:30:23", "01-Mar-19 7:35:03", "01-Mar-19 7: 35:08" ), 用法 = c("8 sec", "12 sec", "2 sec", "5 sec")), row.names = c(NA, -4L), class= c("tbl_df ", "tbl", "data.frame"))
  • 感谢您的洞察和欢迎!

标签: r dplyr tidyr


【解决方案1】:

如果您想将usage 列转换为秒,我们可以使用grepl 找出其中包含"min" 的值并将它们乘以60。

df$seconds <- with(df, ifelse(grepl('min', usage), 
       as.integer(gsub('\\D', '', usage)) * 60, as.integer(gsub('\\D', '', usage))))

df
#    application              start                end  usage seconds
#1 reddit is fun 01-Mar-19 17:37:26 01-Mar-19 17:37:36 10 sec      10
#2          Maps 01-Mar-19 17:37:38  01-Mar-19 17:41:1  3 min     180
#3         Clock 01-Mar-19 17:41:10 01-Mar-19 17:41:21 11 sec      11

但是,我同意 @Calum You 使用 startend 列来获取 usage 以秒为单位的时间

library(dplyr)
library(lubridate)

df %>%
  mutate_at(vars(start, end), dmy_hms) %>%
  mutate(seconds = as.integer(end - start))

数据

df <- structure(list(application = structure(3:1, .Label = c("Clock", 
"Maps", "reddit is fun"), class = "factor"), start = structure(1:3, 
.Label = c("01-Mar-19 17:37:26", "01-Mar-19 17:37:38", "01-Mar-19 17:41:10"), 
class = "factor"), end = structure(1:3, .Label = c("01-Mar-19 17:37:36", 
"01-Mar-19 17:41:1", "01-Mar-19 17:41:21"), class = "factor"), usage =
structure(c(1L,3L, 2L), .Label = c("10 sec", "11 sec", "3 min"), 
class = "factor")), row.names = c(NA, -3L), class = "data.frame")

【讨论】:

  • 我已经加载了 lubridate 和 dplyr 库,方便!使用 start 和 end 效果很好!谢谢!我是 R 新手,这个解决方案简单而美妙。
【解决方案2】:

您好,欢迎来到 SO!

要为 Ronak 提出的答案提供替代方案(可能不是最好的),您可以这样做:

sapply(usage, function(x){
  if(length(x[grep("min",x)]) != 0) 
    {
    x[grep("min",x)] = as.character(paste0(as.numeric(gsub(" min","",x))*60," sec"))
  }
  else{x = x}
})

使用您的示例,它将给出以下输出:

usage = c("10 sec","3 min","11 sec")

> sapply(usage, function(x){
+   if(length(x[grep("min",x)]) != 0) 
+     { x[grep("min",x)] = as.character(paste0(as.numeric(gsub(" min","",x))*60," sec"))}
+   else{x = x}
+ })
   10 sec     3 min    11 sec 
 "10 sec" "180 sec"  "11 sec" 

然后,您可以使用此输出替换您的 usage 列。

【讨论】:

  • 谢谢 dc37! sapply我不熟悉,我会把它放在我的研究列表中。
  • 不客气!这主要是因为我对dplyr 不是很熟悉,所以我必须找到一些技巧来做几乎相同的事情。
猜你喜欢
  • 2012-11-21
  • 1970-01-01
  • 2019-05-24
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 2020-09-16
  • 2013-04-15
  • 1970-01-01
相关资源
最近更新 更多