У меня есть набор данных с 8 столбцами, 7 столбцов из 8 - столбцы даты. Мне нужно сравнить дату в одном столбце, скажем ReferenceDate, с датами в других столбцах, например DateCol1, DateCol2, DateCol3, DateCol4, DateCol5, DateCol6, DateCol7

ID   DateCol1   DateCol2   DateCol3   DateCol4   ReferenceDate DateCol5   DateCol6   DateCol7
12  2000-11-03  2007-05-17 2003-07-11 2014-03-19 2000-07-11    1999-10-06 2015-06-29 2014-07-06 
17  2015-12-16  2017-07-26 2015-01-13 2020-01-30 2015-03-08    2007-07-30 2020-05-21 2010-10-09 
19  2003-03-06  2011-02-23 2001-09-18 2001-04-05 2013-05-17    1999-10-02 2004-08-26 2019-04-15 
23  2002-10-06  2019-03-12 1999-04-19 2008-04-03 2006-11-20    2000-11-15 2010-07-22 1999-05-27 
22  2019-05-19  2014-11-17 2001-03-24 2003-07-03 2001-04-02    2017-06-03 2016-09-21 2013-07-13

Моя цель - создать значение столбца Yes/No, которое указывает, была ли дата в столбце ReferenceDate раньше или позже любой из дат в 7 других столбцах дат.

ID   DateCol1   DateCol2   DateCol3   DateCol4   ReferenceDate DateCol5   DateCol6   DateCol7    Status
12  2000-11-03  2007-05-17 2003-07-11 2014-03-19 2000-07-11    1999-10-06 2015-06-29 2014-07-06  Yes (DateCol5 earlier than Reference Date)
17  2015-12-16  2017-07-26 2015-01-13 2020-01-30 2015-03-08    2007-07-30 2020-05-21 2010-10-09  Yes (DateCol5 earlier than Reference Date)
19  2003-03-06  1981-02-23 2001-09-18 2001-04-05 2013-05-17    1999-10-02 2004-08-26 2019-04-15  Yes (DateCol2 earlier than Reference Date)
23  1992-10-06  2019-03-12 1999-04-19 2008-04-03 2006-11-20    2000-11-15 2010-07-22 1999-05-27  Yes (DateCol1 earlier than Reference Date)
22  2019-05-19  2014-11-17 2001-03-24 2003-07-03 2001-04-02    2017-06-03 2016-09-21 2013-07-13  No

Полагаю, я мог бы сделать это, используя множество вложенных ifelse, но я бы просто сошел с ума. Мне нужна помощь, как сделать это более эффективно. Заранее спасибо.

1
bison2178 20 Янв 2021 в 01:47

3 ответа

Лучший ответ

Вариант с rowSums заключался бы в том, чтобы select столбцы 'Date', выполнить сравнение со столбцом 'ReferenceDate', проверить, не равен ли вывод rowSums 0, преобразовать логическое значение в числовой индекс (добавьте 1) и используйте его для замены значений на «Да», «Нет»

nm1 <- grep('^DateCol', names(df1), value = TRUE)

Или, если имена столбцов не являются шаблонами DateCol, может быть

nm1 <- setdiff(names(df1), c("ID", "ReferenceDate"))
df1$flag <- c("No", "Yes")[(rowSums(df1[nm1] > df1$ReferenceDate) != 0) + 1]
2
akrun 19 Янв 2021 в 23:17

Используя dplyr rowwise:

library(dplyr)

df %>%
  rowwise() %>%
  mutate(Status = if(any(c_across(starts_with('DateCol')) < ReferenceDate)) 
                  'Yes' else 'No') -> result

result
0
Ronak Shah 20 Янв 2021 в 04:50

Возможно это может помочь

df$Status <- ifelse(rowSums(sapply(df[-1], `<`, df$ReferenceDate)) > 0, "Yes", "No")

Что дает (не знаю, почему последняя строка желаемого результата дает "Нет")

> df
  ID   DateCol1   DateCol2   DateCol3   DateCol4 ReferenceDate   DateCol5
1 12 2000-11-03 2007-05-17 2003-07-11 2014-03-19    2000-07-11 1999-10-06
2 17 2015-12-16 2017-07-26 2015-01-13 2020-01-30    2015-03-08 2007-07-30
3 19 2003-03-06 2011-02-23 2001-09-18 2001-04-05    2013-05-17 1999-10-02
4 23 2002-10-06 2019-03-12 1999-04-19 2008-04-03    2006-11-20 2000-11-15
5 22 2003-05-19 2014-11-17 2001-03-24 2003-07-03    2014-04-02 2017-06-03
    DateCol6   DateCol7 Status
1 2015-06-29 2014-07-06    Yes
2 2020-05-21 2010-10-09    Yes
3 2004-08-26 2019-04-15    Yes
4 2010-07-22 1999-05-27    Yes
5 2016-09-21 2013-07-13    Yes

Данные

> dput(df)
structure(list(ID = c(12L, 17L, 19L, 23L, 22L), DateCol1 = structure(c(11264,
16785, 12117, 11966, 12191), class = "Date"), DateCol2 = structure(c(13650,
17373, 15028, 17967, 16391), class = "Date"), DateCol3 = structure(c(12244,
16448, 11583, 10700, 11405), class = "Date"), DateCol4 = structure(c(16148,
18291, 11417, 13972, 12236), class = "Date"), ReferenceDate = structure(c(11149,
16502, 15842, 13472, 16162), class = "Date"), DateCol5 = structure(c(10870,
13724, 10866, 11276, 17320), class = "Date"), DateCol6 = structure(c(16615,
18403, 12656, 14812, 17065), class = "Date"), DateCol7 = structure(c(16257,
14891, 18001, 10738, 15899), class = "Date")), row.names = c(NA,
-5L), class = "data.frame")
2
ThomasIsCoding 19 Янв 2021 в 23:15