Сравните даты в строке и устраните конфликты

У меня есть фрейм данных с идентификатором и три столбца даты, которые должны быть одинаковыми в каждой строке, но иногда возникают конфликты.

Для каждой строки я хочу сравнить три даты, и если хотя бы две совпадают, то поставить эту дату, а если все не согласны, то поставить NA.

Это немного осложняется тем, что есть также NA для неизвестных дат. Если есть два АН и одна дата, я буду рад сохранить эту единственную дату.

Я мог бы сделать это с кучей ifelse, но мне было интересно, есть ли изящный способ сделать это.

Примером проблемы является этот кадр данных:

dataDF <- data.frame(
  id = c(1,2,3,4,5,6),
  date1 = as.Date(c('2000-01-01', '2000-05-01', NA,            NA,          '2000-01-05', NA)),
  date2 = as.Date(c('2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04', '2000-01-06', NA)),
  date3 = as.Date(c(NA,           '2000-01-02', '2000-05-03',  NA         , '2000-01-07', NA))

)

Я хотел бы получить новый чистый столбец date, чтобы фрейм данных выглядел следующим образом:

  id      date1      date2      date3       date
1  1 2000-01-01 2000-01-01       <NA> 2000-01-01
2  2 2000-05-01 2000-01-02 2000-01-02 2000-01-02
3  3       <NA> 2000-01-03 2000-05-03       <NA>
4  4       <NA> 2000-01-04       <NA> 2000-01-04
5  5 2000-01-05 2000-01-06 2000-01-07       <NA>
6  6       <NA>       <NA>       <NA>       <NA>

заранее спасибо


person user1165199    schedule 28.02.2018    source источник


Ответы (1)


Это работает.

Объяснение:
Эта функция работает следующим образом:
1. Для каждой строки, если все значения NA, она возвращает NA
2. Для каждой строки, если все значения уникальны, он возвращает NA.
3. Если в строке есть 2 NA, возвращается значение, отличное от NA.
4. В противном случае возвращается одно из значений, встречающихся дважды.

# helper function
get_values <- function(x)
{
    if (all(is.na(x)) | length(unique(x)) == 3) return (NA)
    else if ((length(unique(x)) == 1) & (! any(is.na(x)))) return (unique(x))
    else if (sum(is.na(x)) == 2) return (x[!is.na(x)])
    else return(as.character(x[duplicated(x)]))

}


# apply function row wise
dataDF$date <- apply(dataDF[,-1], 1, get_values)

  id      date1      date2      date3       date
1  1 2000-01-01 2000-01-01       <NA> 2000-01-01
2  2 2000-05-01 2000-01-02 2000-01-02 2000-01-02
3  3       <NA> 2000-01-03 2000-05-03       <NA>
4  4       <NA> 2000-01-04       <NA> 2000-01-04
5  5 2000-01-05 2000-01-06 2000-01-07       <NA>
6  6       <NA>       <NA>       <NA>       <NA>
person YOLO    schedule 28.02.2018
comment
Спасибо, но не совсем работает, если у меня есть 3 одинаковых значения, он дважды возвращает их в чистом столбце. Это достаточно близко, так что придется поиграть и, надеюсь, получить его - person user1165199; 02.03.2018
comment
Спасибо, что дали мне знать. Я добавил еще один случай в функцию. Теперь он возвращает уникальное значение, когда все три даты совпадают. - person YOLO; 02.03.2018