Изменить строки с другим форматом на даты с тем же форматом в кадре данных - PullRequest
0 голосов
/ 27 мая 2019

У меня есть фрейм данных, который выглядит следующим образом (он содержит несколько строк строк с датами от 18xx до 2019 года)

                date
1   25 February 1987
2     20 August 1974
3     9 October 1984
4          16-Oct-63
5         13-11-1961
6           03/23/87
7         01.01.1995
8      February 1988
9               1988
10 20050101-20051231

Мне нужно изменить столбец даты на один формат даты (например: ГГГГ-ММ-ДД или любой другой). Поскольку для идентификатора 9 есть только некоторые значения года, я также должен их автоматически заполнить. Это всегда должно приводить к последнему дню конкретного года. Если для идентификатора 8 это месяц и год, то он всегда должен заполнять последний день конкретного месяца (и проверять, был ли это високосный год, как это было в 1988 году, и возвращать в этом случае что-то вроде 1988-02-29 ). Если это временной интервал, как в последнем ряду, он всегда должен обрезать первую часть и изменить его на 31 декабря данного года. Как я могу это сделать?

Я думал об использовании пакета lubridate или пакета anytime. С lubridate и parse_date или parse_date_time. Это даже работает, но всегда заполняет пропущенные значения дней до первого дня месяца, а не до последнего.

library(lubridate)

date <- c("25 February 1987", "20 August 1974", "9 October 1984", "16-Oct-63", "13-11-1961", "03/23/87", "01.01.1995",
          "February 1988", "1988", "20050101-20051231")

df <- as.data.frame(date)

parse_date(df$date)

parse_date_time(x = df$date,
                orders = c("d m y", "d B Y", "d/m/Y","B Y", "Y", "m/d/y",
                           "Ymd-Ymd"),
                locale = "eng")

Мои фактические результаты

(parse_date(df$date)): 

 [1] "1987-02-25 UTC" "1974-08-20 UTC" "1984-10-09 UTC" "2019-10-16 UTC" "2019-11-13 UTC" "1987-03-23 UTC" "1995-01-01 UTC"
 [8] "1988-02-01 UTC" "1988-01-01 UTC" "2005-12-31 UTC"

В течение parse_date_time я остро получаю ошибку из-за последних ордеров "Ymd-Ymd" (Если я просто проверю: parse_date("20050101-20051231") it results in "2005-12-31 UTC", что я действительно хочу иметь!)

Ответы [ 2 ]

0 голосов
/ 28 мая 2019

Спасибо. Это очень близко. К сожалению, это все еще дает мне неправильные выходные даты для некоторых записей.

               date    newdate   newdate2
1   25 February 1987 1987-02-25 1987-02-25
2     20 August 1974 1974-08-20 1974-08-20
3     9 October 1984 1984-10-09 1984-10-09
4          16-Oct-63 2063-10-16 1963-10-16
5         13-11-1961 1961-11-13 1961-11-13
6           03/23/87 1987-03-23 1987-03-23
7         01.01.1995 1995-01-01 1995-01-01
8      February 1988 1988-02-19 1988-02-19
9               1988 1988-01-01 1988-01-01
10 20050101-20051231       <NA> 2005-01-01

Но мне нужно вот так:

               date    newdate   newdate2
1   25 February 1987 1987-02-25 1987-02-25
2     20 August 1974 1974-08-20 1974-08-20
3     9 October 1984 1984-10-09 1984-10-09
4          16-Oct-63 2063-10-16 1963-10-16
5         13-11-1961 1961-11-13 1961-11-13
6           03/23/87 1987-03-23 1987-03-23
7         01.01.1995 1995-01-01 1995-01-01
8      February 1988 1988-02-19 **1988-02-29**
9               1988 1988-01-01 **1988-12-31**
10 20050101-20051231       <NA> **2005-12-31**

Это означает: если у меня есть только год и месяц: мне нужно ввести последний день конкретного месяца и февраль, чтобы учесть високосные годы, как в строке примера 8. Если у меня есть только год, мне нужно измените его на 31 декабря данного года. И если запись выглядит как в строке 10, мне нужно вырезать первую часть и просто сохранить 31 декабря данного года, но для этого случая я уже скорректировал часть вашего кода:

is.na(newdate) ~ paste0(substr(x=date, start = 10, stop = 13), "-", 
                            substr(x=date, start = 14, stop = 15), "-",
                            substr(x=date, start = 16, stop = 17) )
0 голосов
/ 27 мая 2019

Использование шпаргалки (https://evoldyn.gitlab.io/evomics-2018/ref-sheets/R_lubridate.pdf)) методом проб и ошибок с dplyr:

df %>% 
        mutate(newdate = parse_date_time(x = date, orders = c("dmy", "mdy", "my", "y")) ) %>% 
        mutate(newdate2 = case_when(
                        newdate > today() ~ newdate - 100*365.25*24*3600,
                        is.na(newdate) ~ paste0(substr(x=date, start = 1, stop = 4), "-", 
                                                substr(x=date, start = 5, stop = 6), "-",
                                                substr(x=date, start = 7, stop = 8) )
                        %>%
                                parse_date_time(., orders = c("dmy", "mdy", "my", "y", "ymd")),
                        TRUE ~ newdate
        )
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...