Во время написания этого вопроса я обнаружил липкую штукатурку, но все равно решил написать, потому что мне потребовался день, чтобы потренироваться. Конечная проблема, которую я в конечном итоге обнаружил, состоит в том, что 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
, и я получу желаемый результат