pmin (, na.rm = T) возвращает NA при сравнении дат, сгенерированных с помощью ave () - PullRequest
0 голосов
/ 28 марта 2020

Во время написания этого вопроса я обнаружил липкую штукатурку, но все равно решил написать, потому что мне потребовался день, чтобы потренироваться. Конечная проблема, которую я в конечном итоге обнаружил, состоит в том, что min (..., na.rm = T) для дат, которые все являются NA, дает результат, который выглядит как NA, но на самом деле -Inf. И при последующей обработке они не рассматриваются как NA.

> mymindate <- min(structure(c(NA), class = "Date"), na.rm=T)
Warning message:
In min.default(NA, na.rm = TRUE) :
  no non-missing arguments to min; returning Inf
> mymindate  # appears to be NA when printed
[1] NA
> is.na(mymindate)  # but isn't
[1] FALSE
> dput(mymindate)   # it's actually Inf (the clue was in the warning message to be fair)
structure(Inf, class = "Date")

Я понимаю, что это, вероятно, просто так, и нет никакого ответа, кроме как запомнить его и не попасть в ловушку снова.

Вот моя первоначальная проблема, которую я использую ave, чтобы найти минимальную дату начала и максимальную дату окончания по идентификатору. Некоторые даты окончания могут отсутствовать. Затем я использую pmin, чтобы найти самую раннюю дату окончания и две другие даты. Моя проблема в ID3, где результат ave (..., max) в 'maxEnd' равен NA, тогда результат pmin () в 'Output' равен NA.

<------------Input Data------------------------><--------Output Data ------------><-Want---->
 ID      DateA      DateB      Start        End   minStart     maxEnd      Output      Want 
  1 2018-01-10       <NA> 2015-05-01 2015-06-28 2015-05-01 2015-08-06  2015-08-06  2015-08-06 
  1 2018-01-10       <NA> 2015-07-06 2015-08-06 2015-05-01 2015-08-06  2015-08-06  2015-08-06 
  1 2018-01-10       <NA> 2015-09-17       <NA> 2015-05-01 2015-08-06  2015-08-06  2015-08-06 
  2       <NA> 2019-12-31 2016-04-20 2016-05-27 2016-04-20 2016-07-16  2016-07-16  2016-07-16 
  2       <NA> 2019-12-31 2016-07-02 2016-07-16 2016-04-20 2016-07-16  2016-07-16  2016-07-16 
  3 2016-02-15       <NA> 2015-07-15       <NA> 2015-07-15       <NA>        <NA>  2016-02-15

Вот код

  structure(
    list(
      ID = c(1L, 1L, 1L, 2L, 2L, 3L),
      DateA = structure(c(17541,17541, 17541, NA, NA, 16846), class = "Date"),
      DateB = structure(c(NA,NA, NA, 18261, 18261, NA), class = "Date"),
      Start = structure(c(16556,16622, 16695, 16911, 16984, 16631), class = "Date"),
      End = structure(c(16614,16653, NA, 16948, 16998, NA), class = "Date")
    ),
    row.names = c(NA,-6L),
    class = "data.frame"
  )
df$minStart <- with(df, ave(Start,ID,FUN = function(x) min(x , na.rm = T)))
df$maxEnd <- with(df, ave(End,ID,FUN = function(x) max(x , na.rm = T)))
df$Output <- pmin(df$DateA, df$DateB, df$maxEnd, na.rm = T)

Если я сделаю аналогичный pmin, используя исходный столбец 'End', я не получу никаких NA, как ожидалось

> pmin(df$DateA, df$DateB, df$End, na.rm = T)
[1] "2015-06-28" "2015-08-06" "2018-01-10" "2016-05-27" "2016-07-16" "2016-02-15"

'maxEnd' и 'End' - обе даты с NA

> df$maxEnd
[1] "2015-08-06" "2015-08-06" "2015-08-06" "2016-07-16" "2016-07-16" NA          
> df$End
[1] "2015-06-28" "2015-08-06" NA           "2016-05-27" "2016-07-16" NA 

Но NA в 'maxEnd' на самом деле не являются NA

> is.na(df$maxEnd)
[1] FALSE FALSE FALSE FALSE FALSE FALSE
> is.na(df$End)
[1] FALSE FALSE  TRUE FALSE FALSE  TRUE

При запуске оператора ave () (no non-missing arguments to max; returning -Inf) появлялись предупреждающие сообщения. Оказывается, что NA в 'maxEnd' на самом деле '-Inf'.

> dput(df$maxEnd)
structure(c(16653, 16653, 16653, 16998, 16998, -Inf), class = "Date")
> df$maxEnd==-Inf
[1] FALSE FALSE FALSE FALSE FALSE  TRUE
> df$maxEnd[df$maxEnd==-Inf]
[1] NA

Таким образом, моя исправленная штукатурка - просто заменить -Inf на NA на df$maxEnd[df$maxEnd==-Inf]<-NA или df$maxEnd[!is.finite(df$maxEnd)]<-NA, и я получу желаемый результат

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...