#r #dataframe #date #lubridate
#r #dataframe #Дата #lubridate
Вопрос:
У меня есть
> head(p, 10)
date_contact mr_daterd_fu1
1 11.10.2012
2
3
4
5 13.12.1994
6
7 20.03.2012 20.03.2012
8 25.08.1999
9 25.05.2012 25.05.2012
10 19.10.2007
Мне нужно заменить отсутствующие значения в p$date_contact
на p$mr_daterd_fu1
as в
fu1_date = ifelse(is.na(date_contact),
as.Date(mr_daterd_fu1, format = '%d.%m.%Y'),
as.Date(date_contact, format = '%d.%m.%Y')))
Но это дает
> head(p, 10)
date_contact mr_daterd_fu1 fu1_date
1 11.10.2012 NA
2 NA
3 NA
4 NA
5 13.12.1994 9112
6 NA
7 20.03.2012 20.03.2012 15419
8 25.08.1999 10828
9 25.05.2012 25.05.2012 15485
10 19.10.2007 13805
И
> str(p)
'data.frame': 946 obs. of 3 variables:
$ date_contact : chr "" "" "" "" ...
$ mr_daterd_fu1: chr "11.10.2012" "" "" "" ...
$ fu1_date : num NA NA NA NA 9112 ...
Почему p$fu1_date
не отображается as.Date
?
Я пытался
p %>% mutate(mr_daterd_fu1 = as.Date(mr_daterd_fu1, format = '%d.%m.%Y'),
fu1_date = ifelse(is.na(date_contact),
mr_daterd_fu1,
as.Date(date_contact, format = '%d.%m.%Y', origin=mr_daterd_fu1)))
Но это не сработало.
Ожидаемый результат:
date_contact mr_daterd_fu1 fu1_date
1 11.10.2012 2012.10.11
2 NA
3 NA
4 NA
5 13.12.1994 1994.12.13
6 NA
7 20.03.2012 20.03.2012 2012.03.20
8 25.08.1999 1999.08.25
9 25.05.2012 25.05.2012 2012.05.25
10 19.10.2007 2007.10.19
Данные
p <- structure(list(date_contact = c("", "", "", "", "13.12.1994",
"", "20.03.2012", "25.08.1999", "25.05.2012", "19.10.2007"),
mr_daterd_fu1 = c("11.10.2012", "", "", "", "", "", "20.03.2012",
"", "25.05.2012", "")), row.names = c(NA, 10L), class = "data.frame")
Ответ №1:
Мы можем преобразовать в Date
класс и использовать coalesce
library(dplyr)
p %>%
mutate(across(c(date_contact, mr_daterd_fu1),
as.Date, format = "%d.%m.%Y")) %>%
mutate(ful_date = coalesce(date_contact, mr_daterd_fu1 ))
-вывод
# date_contact mr_daterd_fu1 ful_date
#1 <NA> 2012-10-11 2012-10-11
#2 <NA> <NA> <NA>
#3 <NA> <NA> <NA>
#4 <NA> <NA> <NA>
#5 1994-12-13 <NA> 1994-12-13
#6 <NA> <NA> <NA>
#7 2012-03-20 2012-03-20 2012-03-20
#8 1999-08-25 <NA> 1999-08-25
#9 2012-05-25 2012-05-25 2012-05-25
#10 2007-10-19 <NA> 2007-10-19
В общем, лучше не использовать ifelse
с Date
class
Комментарии:
1. Привет, акрун. Спасибо за ваш вклад. В моем наборе данных есть множество ковариаций, поэтому
across(everything()..
их не следует преобразовыватьas.Date
, только ковариации, упомянутые в вопросе.2. Привет @akrun — дополнительный вопрос; возможно ли применить ваш метод как-то к эффекту:
mutate(across(c("all columns that contain "date_contact", all columns that contain "mr_daterd"), as.Date, format = "%d.%m.%Y"))
?3. Вы можете использовать
matches("date_contact|mr_daterd")
4. Спасибо за быстрый ответ. Получено сообщение об ошибке
mutate(across(matches(date_contact | mr_daterd), as.Date, format = "%d.%m.%Y"))
. Я думаю, это потому, что столбцы содержатdate_contact
иmr_daterd
как часть большего имени столбца, например.mr_daterd_fu1
. Поэтому он должен выглядеть примерно такall columns that contain date_contact|mr_daterd
— можно ли это сделать?5. @cmirian большинство помощников по выбору принимают строку, т.е.
contains
matches
…
Ответ №2:
Вы также можете попробовать это. В ваших данных есть пустые места, поэтому is.na()
они не работают:
library(dplyr)
#Code
p %>% mutate(mr_daterd_fu1 = as.Date(mr_daterd_fu1, format = '%d.%m.%Y'),
fu1_date = if_else(date_contact=='',
mr_daterd_fu1,
as.Date(date_contact, format = '%d.%m.%Y', origin=mr_daterd_fu1)))
Вывод:
date_contact mr_daterd_fu1 fu1_date
1 2012-10-11 2012-10-11
2 <NA> <NA>
3 <NA> <NA>
4 <NA> <NA>
5 13.12.1994 <NA> 1994-12-13
6 <NA> <NA>
7 20.03.2012 2012-03-20 2012-03-20
8 25.08.1999 <NA> 1999-08-25
9 25.05.2012 2012-05-25 2012-05-25
10 19.10.2007 <NA> 2007-10-19