将负数转换为 Date 或 POSIXct 对象

Transforming negative numbers to Date or POSIXct object

我一直想将一些 4 到 2 位负数(表示 BCE 日期)转换为 Date 对象。在此之前,我想合并年、月和日列以形成一个列。 如果你们知道我如何使用 lubridate 做到这一点,我将不胜感激。

> NOAA_data %>% slice(10:30)
# A tibble: 21 x 39
   `Search Paramet~  Year    Mo    Dy    Hr    Mn   Sec   Tsu   Vol `Location Name` Latitude
   <chr>            <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>              <dbl>
 1 NA               -1050    NA    NA    NA    NA     0    NA    NA JORDAN:  SW:  ~     29.6
 2 NA                -759    NA    NA    NA    NA     0    NA    NA ISRAEL:  JERUS~     33  
 3 NA                -590    NA    NA    NA    NA    NA     7    NA LEBANON:  SUR ~     33.3
 4 NA                -550    NA    NA    NA    NA    NA    NA    NA GREECE:  MOUNT~     37  
 5 NA                -525    NA    NA    NA    NA    NA     8    NA LEBANON:  SUR ~     33.6
 6 NA                -480     9    29    NA    NA    NA  3469    NA GREECE:  SARON~     37.9
 7 NA                -479    NA    NA    NA    NA    NA     9    NA GREECE:  MACED~     39.7
 8 NA                -432    NA    NA    NA    NA    NA    NA    NA GREECE:  ROMAN~     37  
 9 NA                -426     6    NA    NA    NA    NA    10    NA GREECE:  EUBOEA     38.9
10 NA                -400    NA    NA    NA    NA    NA    NA    NA IRAN:  REY,EIV~     35.5

非常感谢您。

我认为目前的最佳做法是在 CE 中设置日期,然后减去年份以获得 BCE。算术可能很粗略,因为没有零年,但这个例子似乎按预期工作:

lubridate::ymd("0000-09-29") - lubridate::years(480)

有关详细信息,您可以查看 Tayflo's exhaustive explanation 关于 lubridate 关于 BCE 日期的 github 问题,该问题几天前刚刚重新开放。

编辑: 对于您的特定数据,您只需将值粘贴到 lubridate::ymd_hms() 函数中,它会将其解析为单个列

NOAA_data %>% mutate(date = ymd_hms(paste0(c('0000','-', Mo,'-', Dy,
                                           '_', Hr,':', Mn, ':', Sec))) - 
                                     lubridate::years(Year))

您还必须为您的 NA 添加一些 ifelse(),将每个设置为合理的默认值(例如,01 表示天,00 表示分钟,等等)。我不会将它添加到我的示例代码中,因为它会更难阅读。

一种方法可能是实验性 gregorian 包:

#remotes::install_github("edgararuiz/gregorian")
library(gregorian); library(dplyr)
data %>%
  mutate(across(Mo:Dy, replace_na, 1)) %>%
  mutate(Date = as_gregorian(paste0(Year,"-",Mo,"-",Dy)))
#   Search.Paramet  Year Mo Dy Hr Mn Sec  Tsu Vol    Location.Name Latitude                                                                        Date
#1              NA -1050  1  1 NA NA   0   NA  NA  JORDAN:  SW:  ~     29.6    1051, 1, 1, TRUE, Thursday, 4, -1050-01-01, Thursday January 1, 1051 BCE
#2              NA  -759  1  1 NA NA   0   NA  NA  ISRAEL:  JERUS~     33.0         760, 1, 1, TRUE, Tuesday, 2, -759-01-01, Tuesday January 1, 760 BCE
#3              NA  -590  1  1 NA NA  NA    7  NA  LEBANON:  SUR ~     33.3           591, 1, 1, TRUE, Monday, 1, -590-01-01, Monday January 1, 591 BCE
#4              NA  -550  1  1 NA NA  NA   NA  NA  GREECE:  MOUNT~     37.0         551, 1, 1, TRUE, Tuesday, 2, -550-01-01, Tuesday January 1, 551 BCE
#5              NA  -525  1  1 NA NA  NA    8  NA  LEBANON:  SUR ~     33.6           526, 1, 1, TRUE, Friday, 5, -525-01-01, Friday January 1, 526 BCE
#6              NA  -480  9 29 NA NA  NA 3469  NA  GREECE:  SARON~     37.9 481, 9, 29, TRUE, Wednesday, 3, -480-09-29, Wednesday September 29, 481 BCE
#7              NA  -479  1  1 NA NA  NA    9  NA  GREECE:  MACED~     39.7       480, 1, 1, TRUE, Saturday, 6, -479-01-01, Saturday January 1, 480 BCE
#8              NA  -432  1  1 NA NA  NA   NA  NA GREECE:  ROMAN~      37.0           433, 1, 1, TRUE, Monday, 1, -432-01-01, Monday January 1, 433 BCE
#9              NA  -426  6  1 NA NA  NA   10  NA  GREECE:  EUBOEA     38.9          427, 6, 1, TRUE, Saturday, 6, -426-06-01, Saturday June 1, 427 BCE
#10             NA  -400  1  1 NA NA  NA   NA  NA  IRAN:  REY,EIV~     35.5       401, 1, 1, TRUE, Saturday, 6, -400-01-01, Saturday January 1, 401 BCE