【问题标题】:Datetime column to list column of parts列出零件列的日期时间列
【发布时间】:2017-03-14 12:44:58
【问题描述】:

我有一个带有日期列的小标题:

df <- structure(list(date = structure(c(1489494191.81966, 1489494125.153, 
    1489494058.48633, 1489493991.81966, 1489493925.153, 1489493858.48633, 
    1489493791.81966, 1489493725.153, 1489493658.48633, 1489493591.81966
    ), class = c("POSIXct", "POSIXt"), tzone = "")), .Names = "date", class = c("tbl_df", 
    "tbl", "data.frame"), row.names = c(NA, -10L))

df

# A tibble: 10 × 1
                  date
                <dttm>
1  2017-03-14 13:23:11
2  2017-03-14 13:22:05
3  2017-03-14 13:20:58
4  2017-03-14 13:19:51
5  2017-03-14 13:18:45
6  2017-03-14 13:17:38
7  2017-03-14 13:16:31
8  2017-03-14 13:15:25
9  2017-03-14 13:14:18
10 2017-03-14 13:13:11

我想将其转换为包含部分列表(年、月、日、小时、分钟、秒)的列表列,例如:

# A tibble: 10 × 1
                     result
                     <list>
1  list(2017,3,14,13,23,11)
2  list(2017,3,14,13,22,5)
3  list(2017,3,14,13,20,58)
4  list(2017,3,14,13,19,51)
5  list(2017,3,14,13,18,45)
6  list(2017,3,14,13,17,38)
7  list(2017,3,14,13,16,31)
8  list(2017,3,14,13,15,25)
9  list(2017,3,14,13,14,18)
10 list(2017,3,14,13,13,11)

我尝试了一堆字符串拆分策略,但它们的效率非常低(实际 df 很大)。列表的组成部分最后必须是整数或数字。

有什么聪明的办法吗?

编辑:

这就是我现在正在做的,但它似乎并没有很好地扩展:

library(lubridate)
library(purrr)

df %>%
  transmute(y = year(date),
            m = month(date),
            d = day(date),
            hh = hour(date),
            mm = minute(date),
            ss = second(date)
         ) %>%
  by_row(c, .to = "result") %>%
  select(result)

# A tibble: 10 × 1
       result
       <list>
1  <list [6]>
2  <list [6]>
3  <list [6]>
4  <list [6]>
5  <list [6]>
6  <list [6]>
7  <list [6]>
8  <list [6]>
9  <list [6]>
10 <list [6]>

【问题讨论】:

  • 我猜df$res &lt;- strsplit(as.character(df$date), " |-|:") 可能是一个开始

标签: r dataframe dplyr tidyr purrr


【解决方案1】:

你可以使用library(lubridate):

library(lubridate)

y <- year(df$date)
m <- month(df$date)
d <- day(df$date)
h <- hour(df$date)
min <- minute(df$date)
s <- as.integer(second(df$date))

然后组合成一个列表。

res <- lapply(1:length(y), function(x){

  return(c(y[x], d[x], d[x], h[x], min[x], s[x]))

})

tibble::tibble(res)

【讨论】:

    【解决方案2】:

    您可以在一行代码中使用data.table 来做到这一点:

    DT[, unclass(as.POSIXlt(date))][, .(year+1900, mon, mday, hour, min, sec)]

    将您的 data.frame 转换为 data.table 并将日期转换为 POSIXlt 格式。

    DT <- as.data.table(df)
    DT[, unclass(as.POSIXlt(date))][, ':=' (year=year+1900, mon=mon+1, sec=floor(sec)) ][, .(year, mon, mday, hour, min, sec)]
    

    这会链接操作,因此结果如下所示:

       year mon mday hour min sec
     1: 2017   3   14    7  23  11
     2: 2017   3   14    7  22   5
     3: 2017   3   14    7  20  58
     4: 2017   3   14    7  19  51
     5: 2017   3   14    7  18  45
     6: 2017   3   14    7  17  38
     7: 2017   3   14    7  16  31
     8: 2017   3   14    7  15  25
     9: 2017   3   14    7  14  18
    10: 2017   3   14    7  13  11
    

    这可能是 R 中处理以您想要的方式分割日期的数百万条记录的最快方式。

    【讨论】:

      猜你喜欢
      • 2013-11-29
      • 2013-01-20
      • 2014-04-19
      • 2018-04-30
      • 1970-01-01
      • 2010-11-04
      • 2021-10-22
      • 2018-09-16
      • 1970-01-01
      相关资源
      最近更新 更多