簡體   English   中英

R中年月日時間串連題

[英]Concatenate year, month, day and time problem in R

我的 dataframe, df中有這些專欄:

year month day hour minute
2013 1     7   21   54
2013 3     20  13   59
2013 1     3   18   40

  .. cols(
  ..   year = col_double(),
  ..   month = col_double(),
  ..   day = col_double(),
  ..   hour = col_double(),
  ..   minute = col_double(),

我想要一個新列datetime

datetime
2013/1/7   21:54
2013/3/20  13:59
2013/1/3   18:40

我試過這個:

library(readr)
library(dplyr)

df$datetime <- with(df, as.POSIXct(paste(year, month, day, hour, minute), 
                                 format = "%Y/%m/%d %H:%M:%S"))

還有這個:

df$DT <- as.POSIXct((paste(df$year, df$month, df$day, df$hour, df$minute)), format="%Y/%m/%d %H:%M:%S")

但是,它給了我所有的NA值。

  • 不過,我可以將年、月和日與 as.Date() 合並。 我怎樣才能增加時間呢?

  • 另外,以后如何按日期時間排序?

您可以使用原始語法,但請確保在日期時間的各個部分之間放置正確的分隔符:

dat <- tibble::tribble(
  ~year, ~month, ~day, ~hour, ~minute,
2013, 1,     7,   21,   54,
2013, 3,     20,  13,   59,
2013, 1,     3,   18,   40)


dat$datetime <- with(dat, as.POSIXct(paste0(year, "/", month, "/", day, " ", hour, ":", minute, ":00"), 
                                   format = "%Y/%m/%d %H:%M:%S"))

dat
#> # A tibble: 3 × 6
#>    year month   day  hour minute datetime           
#>   <dbl> <dbl> <dbl> <dbl>  <dbl> <dttm>             
#> 1  2013     1     7    21     54 2013-01-07 21:54:00
#> 2  2013     3    20    13     59 2013-03-20 13:59:00
#> 3  2013     1     3    18     40 2013-01-03 18:40:00

reprex package (v2.0.1) 創建於 2022-12-06

當您告訴as.POSIXct()格式為"%Y/%m/%d %H:%M:%S"時,它希望看到一個看起來像這樣的字符串(例如, "2013/01/03 13:59:00" )。 您的語法只是將它們與空格粘貼在一起,形成類似於"2013 01 03 13 59"的內容,因此當as.POSIXct()嘗試解析字符串時,它沒有看到預期的分隔符。 您也可以通過維護原始paste()規范並更改格式來獲得相同的結果:

library(dplyr)
dat <- tibble::tribble(
  ~year, ~month, ~day, ~hour, ~minute,
  2013, 1,     7,   21,   54,
  2013, 3,     20,  13,   59,
  2013, 1,     3,   18,   40)


dat$datetime <- with(dat, as.POSIXct(paste(year,  month,  day, hour, minute), 
                                     format = "%Y %m %d %H %M"))

arrange(dat, desc(datetime))
#> # A tibble: 3 × 6
#>    year month   day  hour minute datetime           
#>   <dbl> <dbl> <dbl> <dbl>  <dbl> <dttm>             
#> 1  2013     3    20    13     59 2013-03-20 13:59:00
#> 2  2013     1     7    21     54 2013-01-07 21:54:00
#> 3  2013     1     3    18     40 2013-01-03 18:40:00

reprex package (v2.0.1) 創建於 2022-12-06

最簡單的方法是使用make_datetime中的lubridate 這個 function 直接接受double輸入,所以你不需要自己連接成一個字符串。

library(dplyr)
library(lubridate)

df |> mutate(datetime = make_datetime(year, month, day, hour, minute))

Output:

# A tibble: 3 × 6
   year month   day  hour minute datetime           
  <dbl> <dbl> <dbl> <dbl>  <dbl> <dttm>             
1  2013     1     7    21     54 2013-01-07 21:54:00
2  2013     3    20    13     59 2013-03-20 13:59:00
3  2013     1     3    18     40 2013-01-03 18:40:00

數據:

library(readr)

df <- read_table("year month day hour minute
                 2013 1     7   21   54
                 2013 3     20  13   59
                 2013 1     3   18   40")

更新:這也可以使用arrange進行排序:

library(dplyr)
library(lubridate)

df |> 
  mutate(datetime = make_datetime(year, month, day, hour, minute)) |>
  arrange(datetime)

Output:

# A tibble: 3 × 6
   year month   day  hour minute datetime           
  <dbl> <dbl> <dbl> <dbl>  <dbl> <dttm>             
1  2013     1     3    18     40 2013-01-03 18:40:00
2  2013     1     7    21     54 2013-01-07 21:54:00
3  2013     3    20    13     59 2013-03-20 13:59:00

使用tidyverse替代@DaveArmstrong 的答案:

suppressPackageStartupMessages({
  library(tidyr)
  library(lubridate)
  library(dplyr)
})
#> Warning: package 'lubridate' was built under R version 4.2.2
#> Warning: package 'timechange' was built under R version 4.2.2

test <- tibble::tribble(
  ~year, ~month, ~day, ~hour, ~minute,
  2013, 1,     7,   21,   54,
  2013, 3,     20,  13,   59,
  2013, 1,     3,   18,   40)

test
#> # A tibble: 3 × 5
#>    year month   day  hour minute
#>   <dbl> <dbl> <dbl> <dbl>  <dbl>
#> 1  2013     1     7    21     54
#> 2  2013     3    20    13     59
#> 3  2013     1     3    18     40

test |> 
  unite(col = datetime, everything(), sep = "-", remove = FALSE) |> 
  mutate(
    datetime = ymd_hm(datetime)
  )
#> # A tibble: 3 × 6
#>   datetime             year month   day  hour minute
#>   <dttm>              <dbl> <dbl> <dbl> <dbl>  <dbl>
#> 1 2013-01-07 21:54:00  2013     1     7    21     54
#> 2 2013-03-20 13:59:00  2013     3    20    13     59
#> 3 2013-01-03 18:40:00  2013     1     3    18     40

創建於 2022-12-06,使用reprex v2.0.2

library(magrittr)

df <- tibble::tribble(
  
  ~year, ~month, ~day, ~hour,  ~minute,
  2013, 1,     7, 21,   54,
  2013, 3,     20,  13,   59,
  2013, 1,     3, 18,   40,
  
)

df %>% 
  # pad date elements with leading zeros so parsing works out
  dplyr::mutate(month = stringr::str_pad(month, width = 2, pad = "0"),
                day = stringr::str_pad(day, width = 2, pad = "0")) %>% 
  # parse as actual datetime
  dplyr::mutate(datetime = lubridate::ymd_hm(paste0(year, month, day, hour, minute)))
#> # A tibble: 3 x 6
#>    year month day    hour minute datetime           
#>   <dbl> <chr> <chr> <dbl>  <dbl> <dttm>             
#> 1  2013 01    07       21     54 2013-01-07 21:54:00
#> 2  2013 03    20       13     59 2013-03-20 13:59:00
#> 3  2013 01    03       18     40 2013-01-03 18:40:00

reprex package (v2.0.1) 創建於 2022-12-06

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM